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" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/ui/zoom/zoom_controller.h" 1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/web_applications/web_app.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/aura/window.h" 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/hit_test.h" 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/models/simple_menu_model.h" 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/controls/menu/menu_runner.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/webview/webview.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h" 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/easy_resize_window_targeter.h" 30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/wm/core/shadow_types.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_LINUX) 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/shell_integration_linux.h" 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH) 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/ash_constants.h" 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/ash_switches.h" 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/frame/custom_frame_view_ash.h" 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h" 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell.h" 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/immersive_fullscreen_controller.h" 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/panels/panel_frame_view.h" 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ash/wm/window_properties.h" 4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h" 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ash/wm/window_state_delegate.h" 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/window_state_observer.h" 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/ash/ash_util.h" 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h" 50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ui/aura/client/aura_constants.h" 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/client/window_tree_client.h" 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window_observer.h" 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing extensions::AppWindow; 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMinPanelWidth = 100; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMinPanelHeight = 100; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultPanelWidth = 200; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultPanelHeight = 300; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct AcceleratorMapping { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::KeyboardCode keycode; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int modifiers; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int command_id; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const AcceleratorMapping kAppWindowAcceleratorMap[] = { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F4, ui::EF_ALT_DOWN, IDC_CLOSE_WINDOW }, 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// These accelerators will only be available in kiosk mode. These allow the 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// user to manually zoom app windows. This is only necessary in kiosk mode 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// (in normal mode, the user can zoom via the screen magnifier). 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(xiyuan): Write a test for kiosk accelerators. 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const AcceleratorMapping kAppWindowKioskAppModeAcceleratorMap[] = { 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_MINUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS }, 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_MINUS, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDC_ZOOM_MINUS }, 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_SUBTRACT, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS }, 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_PLUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_PLUS, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_ADD, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL }, 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_NUMPAD0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL }, 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AddAcceleratorsFromMapping(const AcceleratorMapping mapping[], 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t mapping_length, 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::map<ui::Accelerator, int>* accelerators) { 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < mapping_length; ++i) { 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::Accelerator accelerator(mapping[i].keycode, mapping[i].modifiers); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*accelerators)[accelerator] = mapping[i].command_id; 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::map<ui::Accelerator, int>& GetAcceleratorTable() { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::map<ui::Accelerator, int> AcceleratorMap; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CR_DEFINE_STATIC_LOCAL(AcceleratorMap, accelerators, ()); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (accelerators.empty()) { 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddAcceleratorsFromMapping( 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAppWindowAcceleratorMap, 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowAcceleratorMap), 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &accelerators); 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add accelerators for kiosk mode. 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (chrome::IsRunningInForcedAppMode()) { 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddAcceleratorsFromMapping( 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAppWindowKioskAppModeAcceleratorMap, 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowKioskAppModeAcceleratorMap), 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &accelerators); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return accelerators; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(USE_ASH) 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// This class handles a user's fullscreen request (Shift+F4/F4). 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class NativeAppWindowStateDelegate : public ash::wm::WindowStateDelegate, 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public ash::wm::WindowStateObserver, 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public aura::WindowObserver { 1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NativeAppWindowStateDelegate(AppWindow* app_window, 12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extensions::NativeAppWindow* native_app_window) 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : app_window_(app_window), 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_( 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::GetWindowState(native_app_window->GetNativeWindow())) { 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Add a window state observer to exit fullscreen properly in case 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // fullscreen is exited without going through AppWindow::Restore(). This 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is the case when exiting immersive fullscreen via the "Restore" window 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // control. 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(pkotwicz): This is a hack. Remove ASAP. http://crbug.com/319048 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->AddObserver(this); 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->window()->AddObserver(this); 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~NativeAppWindowStateDelegate() { 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (window_state_) { 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->RemoveObserver(this); 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->window()->RemoveObserver(this); 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Overridden from ash::wm::WindowStateDelegate. 1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual bool ToggleFullscreen(ash::wm::WindowState* window_state) OVERRIDE { 1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Windows which cannot be maximized should not be fullscreened. 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(window_state->IsFullscreen() || window_state->CanMaximize()); 1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (window_state->IsFullscreen()) 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->Restore(); 1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else if (window_state->CanMaximize()) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->OSFullscreen(); 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Overridden from ash::wm::WindowStateObserver: 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnPostWindowStateTypeChange( 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::WindowState* window_state, 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::wm::WindowStateType old_type) OVERRIDE { 163a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Since the window state might get set by a window manager, it is possible 164a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // to come here before the application set its |BaseWindow|. 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!window_state->IsFullscreen() && !window_state->IsMinimized() && 166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch app_window_->GetBaseWindow() && 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), 1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu active_frame_color_(SK_ColorBLACK), 1985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu inactive_frame_color_(SK_ColorBLACK) { 1995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ChromeNativeAppWindowViews::~ChromeNativeAppWindowViews() {} 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::OnBeforeWidgetInit( 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::Widget::InitParams* init_params, 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::Widget* widget) {} 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::InitializeDefaultWindow( 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const AppWindow::CreateParams& create_params) { 209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string app_name = web_app::GenerateApplicationNameFromExtensionId( 210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) app_window()->extension_id()); 21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Widget::InitParams init_params(views::Widget::InitParams::TYPE_WINDOW); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_params.delegate = this; 214effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch init_params.remove_standard_frame = IsFrameless() || has_frame_color_; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_params.use_system_default_icon = true; 2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (create_params.alpha_enabled) 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) init_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) init_params.keep_on_top = create_params.always_on_top; 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci init_params.visible_on_all_workspaces = 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci create_params.visible_on_all_workspaces; 22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS) 22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Set up a custom WM_CLASS for app windows. This allows task switchers in 22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // X11 environments to distinguish them from main browser windows. 22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) init_params.wm_class_name = web_app::GetWMClassFromAppName(app_name); 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) init_params.wm_class_class = shell_integration_linux::GetProgramClassName(); 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kX11WindowRoleApp[] = "app"; 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) init_params.wm_role_name = std::string(kX11WindowRoleApp); 22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 23123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) OnBeforeWidgetInit(&init_params, widget()); 23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->Init(init_params); 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The frame insets are required to resolve the bounds specifications 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // correctly. So we set the window bounds and constraints now. 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Insets frame_insets = GetFrameInsets(); 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect window_bounds = create_params.GetInitialWindowBounds(frame_insets); 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SetContentSizeConstraints(create_params.GetContentMinimumSize(frame_insets), 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_params.GetContentMaximumSize(frame_insets)); 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!window_bounds.IsEmpty()) { 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci typedef AppWindow::BoundsSpecification BoundsSpecification; 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool position_specified = 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_bounds.x() != BoundsSpecification::kUnspecifiedPosition && 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_bounds.y() != BoundsSpecification::kUnspecifiedPosition; 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!position_specified) 24623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->CenterWindow(window_bounds.size()); 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) else 24823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->SetBounds(window_bounds); 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 251a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (IsFrameless() && 252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch init_params.opacity == views::Widget::InitParams::TRANSLUCENT_WINDOW) { 253a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // The given window is most likely not rectangular since it uses 254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // transparency and has no standard frame, don't show a shadow for it. 255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // TODO(skuhne): If we run into an application which should have a shadow 256a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // but does not have, a new attribute has to be added. 257a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch wm::SetShadowType(widget()->GetNativeWindow(), wm::SHADOW_TYPE_NONE); 258a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Register accelarators supported by app windows. 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(jeremya/stevenjb): should these be registered for panels too? 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::FocusManager* focus_manager = GetFocusManager(); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::map<ui::Accelerator, int>& accelerator_table = 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetAcceleratorTable(); 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const bool is_kiosk_app_mode = chrome::IsRunningInForcedAppMode(); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ensures that kiosk mode accelerators are enabled when in kiosk mode (to be 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // future proof). This is needed because GetAcceleratorTable() uses a static 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to store data and only checks kiosk mode once. If a platform app is 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // launched before kiosk mode starts, the kiosk accelerators will not be 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // registered. This DCHECK catches the case. 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!is_kiosk_app_mode || 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) accelerator_table.size() == 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowAcceleratorMap) + 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowKioskAppModeAcceleratorMap)); 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Ensure there is a ZoomController in kiosk mode, otherwise the processing 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // of the accelerators will cause a crash. 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!is_kiosk_app_mode || 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ZoomController::FromWebContents(web_view()->GetWebContents())); 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::map<ui::Accelerator, int>::const_iterator iter = 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) accelerator_table.begin(); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != accelerator_table.end(); ++iter) { 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (is_kiosk_app_mode && !chrome::IsCommandAllowedInAppMode(iter->second)) 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) focus_manager->RegisterAccelerator( 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter->first, ui::AcceleratorManager::kNormalPriority, this); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::InitializePanelWindow( 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const AppWindow::CreateParams& create_params) { 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Widget::InitParams params(views::Widget::InitParams::TYPE_PANEL); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.delegate = this; 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect initial_window_bounds = 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_params.GetInitialWindowBounds(gfx::Insets()); 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) preferred_size_ = gfx::Size(initial_window_bounds.width(), 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) initial_window_bounds.height()); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (preferred_size_.width() == 0) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_width(kDefaultPanelWidth); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (preferred_size_.width() < kMinPanelWidth) 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_width(kMinPanelWidth); 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (preferred_size_.height() == 0) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_height(kDefaultPanelHeight); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (preferred_size_.height() < kMinPanelHeight) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_height(kMinPanelHeight); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ash::Shell::HasInstance()) { 313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Open a new panel on the target root. 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* target = ash::Shell::GetTargetRootWindow(); 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.bounds = ash::ScreenUtil::ConvertRectToScreen( 316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) target, gfx::Rect(preferred_size_)); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.bounds = gfx::Rect(preferred_size_); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.bounds = gfx::Rect(preferred_size_); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 32323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->Init(params); 32423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->set_focus_on_creation(create_params.focused); 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuviews::NonClientFrameView* 3285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuChromeNativeAppWindowViews::CreateStandardDesktopAppFrame() { 3295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return views::WidgetDelegateView::CreateNonClientFrameView(widget()); 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)apps::AppWindowFrameView* 3335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuChromeNativeAppWindowViews::CreateNonStandardAppFrame() { 3345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu apps::AppWindowFrameView* frame = 3355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new apps::AppWindowFrameView(widget(), 3365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu this, 3375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu has_frame_color_, 3385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu active_frame_color_, 3395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu inactive_frame_color_); 3405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu frame->Init(); 3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(USE_ASH) 3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // For Aura windows on the Ash desktop the sizes are different and the user 3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // can resize the window from slightly outside the bounds as well. 34423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (chrome::IsNativeWindowInAsh(widget()->GetNativeWindow())) { 3455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu frame->SetResizeSizes(ash::kResizeInsideBoundsSize, 3465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ash::kResizeOutsideBoundsSize, 3475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ash::kResizeAreaCornerSize); 3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 3505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if !defined(OS_CHROMEOS) 3525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // For non-Ash windows, install an easy resize window targeter, which ensures 3535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // that the root window (not the app) receives mouse events on the edges. 3545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (chrome::GetHostDesktopTypeForNativeWindow(widget()->GetNativeWindow()) != 3555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu chrome::HOST_DESKTOP_TYPE_ASH) { 3565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu aura::Window* window = widget()->GetNativeWindow(); 3575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int resize_inside = frame->resize_inside_bounds_size(); 3585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Insets inset( 3595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu resize_inside, resize_inside, resize_inside, resize_inside); 3605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Add the EasyResizeWindowTargeter on the window, not its root window. The 3615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // root window does not have a delegate, which is needed to handle the event 3625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // in Linux. 3635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window->SetEventTargeter(scoped_ptr<ui::EventTargeter>( 3645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new wm::EasyResizeWindowTargeter(window, inset, inset))); 3655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 3665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif 3675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return frame; 3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// ui::BaseWindow implementation. 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 373010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)gfx::Rect ChromeNativeAppWindowViews::GetRestoredBounds() const { 374010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(USE_ASH) 375010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect* bounds = widget()->GetNativeWindow()->GetProperty( 376010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ash::kRestoreBoundsOverrideKey); 377010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (bounds && !bounds->IsEmpty()) 378010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return *bounds; 379010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif 380010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return widget()->GetRestoredBounds(); 381010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 382010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ui::WindowShowState ChromeNativeAppWindowViews::GetRestoredState() const { 384010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if !defined(USE_ASH) 385b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (IsMaximized()) 386b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return ui::SHOW_STATE_MAXIMIZED; 387010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsFullscreen()) 388b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return ui::SHOW_STATE_FULLSCREEN; 389010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#else 390b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Use kRestoreShowStateKey in case a window is minimized/hidden. 39123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::WindowShowState restore_state = widget()->GetNativeWindow()->GetProperty( 39223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) aura::client::kRestoreShowStateKey); 393010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (widget()->GetNativeWindow()->GetProperty( 394010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ash::kRestoreBoundsOverrideKey)) { 395010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If an override is given, we use that restore state (after filtering). 396010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) restore_state = widget()->GetNativeWindow()->GetProperty( 397010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ash::kRestoreShowStateOverrideKey); 398010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 399010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Otherwise first normal states are checked. 400010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsMaximized()) 401010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ui::SHOW_STATE_MAXIMIZED; 402010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsFullscreen()) { 403010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (immersive_fullscreen_controller_.get() && 404010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) immersive_fullscreen_controller_->IsEnabled()) { 405010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Restore windows which were previously in immersive fullscreen to 406010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // maximized. Restoring the window to a different fullscreen type 407010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // makes for a bad experience. 408010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ui::SHOW_STATE_MAXIMIZED; 409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 410010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ui::SHOW_STATE_FULLSCREEN; 411010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 412010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 413ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Whitelist states to return so that invalid and transient states 414ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // are not saved and used to restore windows when they are recreated. 415ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch switch (restore_state) { 416ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_NORMAL: 417ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_MAXIMIZED: 418ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_FULLSCREEN: 419ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return restore_state; 420ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 421ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_DEFAULT: 422ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_MINIMIZED: 423ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_INACTIVE: 424ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_END: 425ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return ui::SHOW_STATE_NORMAL; 426ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 427010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif // !defined(USE_ASH) 428b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return ui::SHOW_STATE_NORMAL; 429b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 430b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::IsAlwaysOnTop() const { 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (app_window()->window_type_is_panel()) { 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(USE_ASH) 43423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return ash::wm::GetWindowState(widget()->GetNativeWindow()) 43523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ->panel_attached(); 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else 437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 44023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return widget()->IsAlwaysOnTop(); 4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// views::ContextMenuController implementation. 445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::ShowContextMenuForView( 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::View* source, 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const gfx::Point& p, 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::MenuSourceType source_type) { 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(USE_ASH) && defined(OS_CHROMEOS) 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<ui::MenuModel> model = 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateMultiUserContextMenu(app_window()->GetNativeWindow()); 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!model.get()) 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Only show context menu if point is in caption. 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point point_in_view_coords(p); 45823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) views::View::ConvertPointFromScreen(widget()->non_client_view(), 459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &point_in_view_coords); 46023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int hit_test = 46123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->non_client_view()->NonClientHitTest(point_in_view_coords); 462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (hit_test == HTCAPTION) { 463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch menu_runner_.reset(new views::MenuRunner( 464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch model.get(), 465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU)); 4665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (menu_runner_->RunMenuAt(source->GetWidget(), 4675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NULL, 4685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect(p, gfx::Size(0, 0)), 4695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::MENU_ANCHOR_TOPLEFT, 470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch source_type) == 4715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::MenuRunner::MENU_DELETED) { 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 4735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// views::WidgetDelegate implementation. 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)gfx::ImageSkia ChromeNativeAppWindowViews::GetWindowAppIcon() { 481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Image app_icon = app_window()->app_icon(); 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (app_icon.IsEmpty()) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetWindowIcon(); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *app_icon.ToImageSkia(); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)gfx::ImageSkia ChromeNativeAppWindowViews::GetWindowIcon() { 489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::WebContents* web_contents = app_window()->web_contents(); 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (web_contents) { 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconTabHelper* favicon_tab_helper = 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconTabHelper::FromWebContents(web_contents); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Image app_icon = favicon_tab_helper->GetFavicon(); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!app_icon.IsEmpty()) 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *app_icon.ToImageSkia(); 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::ImageSkia(); 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)views::NonClientFrameView* ChromeNativeAppWindowViews::CreateNonClientFrameView( 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Widget* widget) { 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (chrome::IsNativeViewInAsh(widget->GetNativeView())) { 504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Set the delegate now because CustomFrameViewAsh sets the 505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // WindowStateDelegate if one is not already set. 506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ash::wm::GetWindowState(GetNativeWindow())->SetDelegate( 507a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<ash::wm::WindowStateDelegate>( 508a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new NativeAppWindowStateDelegate(app_window(), this)).Pass()); 509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (app_window()->window_type_is_panel()) { 511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::PanelFrameView::FrameType frame_type = IsFrameless() ? 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ash::PanelFrameView::FRAME_NONE : ash::PanelFrameView::FRAME_ASH; 513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::NonClientFrameView* frame_view = 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new ash::PanelFrameView(widget, frame_type); 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) frame_view->set_context_menu_controller(this); 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return frame_view; 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (IsFrameless()) 5205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return CreateNonStandardAppFrame(); 5215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ash::CustomFrameViewAsh* custom_frame_view = 5235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new ash::CustomFrameViewAsh(widget); 5245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Non-frameless app windows can be put into immersive fullscreen. 5255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu immersive_fullscreen_controller_.reset( 5265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new ash::ImmersiveFullscreenController()); 5275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu custom_frame_view->InitImmersiveFullscreenControllerForView( 5285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu immersive_fullscreen_controller_.get()); 5295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu custom_frame_view->GetHeaderView()->set_context_menu_controller(this); 5305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return custom_frame_view; 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return (IsFrameless() || has_frame_color_) ? 534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateNonStandardAppFrame() : CreateStandardDesktopAppFrame(); 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 537a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::WidgetHasHitTestMask() const { 538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return shape_ != NULL; 5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::GetWidgetHitTestMask(gfx::Path* mask) const { 542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shape_->getBoundaryPath(mask); 5433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// views::View implementation. 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size ChromeNativeAppWindowViews::GetPreferredSize() const { 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!preferred_size_.IsEmpty()) 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return preferred_size_; 550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NativeAppWindowViews::GetPreferredSize(); 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::AcceleratorPressed( 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ui::Accelerator& accelerator) { 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::map<ui::Accelerator, int>& accelerator_table = 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetAcceleratorTable(); 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<ui::Accelerator, int>::const_iterator iter = 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) accelerator_table.find(accelerator); 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(iter != accelerator_table.end()); 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int command_id = iter->second; 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (command_id) { 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case IDC_CLOSE_WINDOW: 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Close(); 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_ZOOM_MINUS: 566a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_page_zoom::Zoom(web_view()->GetWebContents(), 5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::PAGE_ZOOM_OUT); 5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_ZOOM_NORMAL: 570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_page_zoom::Zoom(web_view()->GetWebContents(), 5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::PAGE_ZOOM_RESET); 5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_ZOOM_PLUS: 574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_page_zoom::Zoom(web_view()->GetWebContents(), 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::PAGE_ZOOM_IN); 5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "Unknown accelerator sent to app window."; 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NativeAppWindowViews::AcceleratorPressed(accelerator); 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NativeAppWindow implementation. 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::SetFullscreen(int fullscreen_types) { 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fullscreen not supported by panels. 587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (app_window()->window_type_is_panel()) 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_fullscreen_ = (fullscreen_types != AppWindow::FULLSCREEN_TYPE_NONE); 59023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->SetFullscreen(is_fullscreen_); 591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(oshima): Remove USE_ATHENA once athena has its own NativeAppWindow. 5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(USE_ASH) && !defined(USE_ATHENA) 594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (immersive_fullscreen_controller_.get()) { 595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |immersive_fullscreen_controller_| should only be set if immersive 596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // fullscreen is the fullscreen type used by the OS. 597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) immersive_fullscreen_controller_->SetEnabled( 5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ImmersiveFullscreenController::WINDOW_TYPE_PACKAGED_APP, 5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (fullscreen_types & AppWindow::FULLSCREEN_TYPE_OS) != 0); 600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Autohide the shelf instead of hiding the shelf completely when only in 601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // OS fullscreen. 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::WindowState* window_state = 60323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ash::wm::GetWindowState(widget()->GetNativeWindow()); 6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_state->set_hide_shelf_when_fullscreen(fullscreen_types != 6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppWindow::FULLSCREEN_TYPE_OS); 606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(ash::Shell::HasInstance()); 607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::Shell::GetInstance()->UpdateShelfVisibility(); 608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(jeremya) we need to call RenderViewHost::ExitFullscreen() if we 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ever drop the window out of fullscreen in response to something that 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // wasn't the app calling webkitCancelFullScreen(). 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::IsFullscreenOrPending() const { 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return is_fullscreen_; 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::UpdateBadgeIcon() { 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Image* icon = NULL; 622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!app_window()->badge_icon().IsEmpty()) { 623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) icon = &app_window()->badge_icon(); 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // chrome::DrawTaskbarDecoration can do interesting things with non-square 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // bitmaps. 6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(benwells): Refactor chrome::DrawTaskbarDecoration to not be avatar 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // specific, and lift this restriction. 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (icon->Width() != icon->Height()) { 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << "Attempt to set a non-square badge; request ignored."; 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::DrawTaskbarDecoration(GetNativeWindow(), icon); 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 636a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::UpdateShape(scoped_ptr<SkRegion> region) { 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool had_shape = shape_; 638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shape_ = region.Pass(); 639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 64023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) aura::Window* native_window = widget()->GetNativeWindow(); 6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (shape_) { 642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) widget()->SetShape(new SkRegion(*shape_)); 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!had_shape) { 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>( 6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new ShapedAppWindowTargeter(native_window, this))); 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 64823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->SetShape(NULL); 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (had_shape) 6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>()); 6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci widget()->OnSizeConstraintsChanged(); 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::HasFrameColor() const { 656a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return has_frame_color_; 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSkColor ChromeNativeAppWindowViews::ActiveFrameColor() const { 6605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return active_frame_color_; 6615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 6625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 6635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSkColor ChromeNativeAppWindowViews::InactiveFrameColor() const { 6645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return inactive_frame_color_; 6655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// NativeAppWindowViews implementation. 6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::InitializeWindow( 670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AppWindow* app_window, 671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const AppWindow::CreateParams& create_params) { 67223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(widget()); 673a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_frame_color_ = create_params.has_frame_color; 6745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu active_frame_color_ = create_params.active_frame_color; 6755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu inactive_frame_color_ = create_params.inactive_frame_color; 676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (create_params.window_type == AppWindow::WINDOW_TYPE_PANEL || 677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_params.window_type == AppWindow::WINDOW_TYPE_V1_PANEL) { 678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) InitializePanelWindow(create_params); 679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) InitializeDefaultWindow(create_params); 681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension_keybinding_registry_.reset(new ExtensionKeybindingRegistryViews( 683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile::FromBrowserContext(app_window->browser_context()), 68423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->GetFocusManager(), 685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY, 686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL)); 687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 688