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" 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/aura/window.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/hit_test.h" 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/models/simple_menu_model.h" 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/controls/menu/menu_runner.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/webview/webview.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h" 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/easy_resize_window_targeter.h" 29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/wm/core/shadow_types.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_LINUX) 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/shell_integration_linux.h" 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH) 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/ash_constants.h" 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/ash_switches.h" 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/frame/custom_frame_view_ash.h" 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h" 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell.h" 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/immersive_fullscreen_controller.h" 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/panels/panel_frame_view.h" 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ash/wm/window_properties.h" 4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h" 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ash/wm/window_state_delegate.h" 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/window_state_observer.h" 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/ash/ash_util.h" 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h" 49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ui/aura/client/aura_constants.h" 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/client/window_tree_client.h" 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window_observer.h" 521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using apps::AppWindow; 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMinPanelWidth = 100; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMinPanelHeight = 100; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultPanelWidth = 200; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultPanelHeight = 300; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct AcceleratorMapping { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::KeyboardCode keycode; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int modifiers; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int command_id; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const AcceleratorMapping kAppWindowAcceleratorMap[] = { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F4, ui::EF_ALT_DOWN, IDC_CLOSE_WINDOW }, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// These accelerators will only be available in kiosk mode. These allow the 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// user to manually zoom app windows. This is only necessary in kiosk mode 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// (in normal mode, the user can zoom via the screen magnifier). 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(xiyuan): Write a test for kiosk accelerators. 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const AcceleratorMapping kAppWindowKioskAppModeAcceleratorMap[] = { 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_MINUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS }, 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_MINUS, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDC_ZOOM_MINUS }, 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_SUBTRACT, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS }, 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_PLUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_PLUS, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_ADD, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL }, 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_NUMPAD0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL }, 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AddAcceleratorsFromMapping(const AcceleratorMapping mapping[], 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t mapping_length, 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::map<ui::Accelerator, int>* accelerators) { 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < mapping_length; ++i) { 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::Accelerator accelerator(mapping[i].keycode, mapping[i].modifiers); 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*accelerators)[accelerator] = mapping[i].command_id; 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::map<ui::Accelerator, int>& GetAcceleratorTable() { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::map<ui::Accelerator, int> AcceleratorMap; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CR_DEFINE_STATIC_LOCAL(AcceleratorMap, accelerators, ()); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (accelerators.empty()) { 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddAcceleratorsFromMapping( 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAppWindowAcceleratorMap, 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowAcceleratorMap), 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &accelerators); 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add accelerators for kiosk mode. 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (chrome::IsRunningInForcedAppMode()) { 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddAcceleratorsFromMapping( 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAppWindowKioskAppModeAcceleratorMap, 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowKioskAppModeAcceleratorMap), 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &accelerators); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return accelerators; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(USE_ASH) 1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// This class handles a user's fullscreen request (Shift+F4/F4). 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class NativeAppWindowStateDelegate : public ash::wm::WindowStateDelegate, 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public ash::wm::WindowStateObserver, 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public aura::WindowObserver { 1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NativeAppWindowStateDelegate(AppWindow* app_window, 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) apps::NativeAppWindow* native_app_window) 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : app_window_(app_window), 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_( 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::GetWindowState(native_app_window->GetNativeWindow())) { 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Add a window state observer to exit fullscreen properly in case 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // fullscreen is exited without going through AppWindow::Restore(). This 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is the case when exiting immersive fullscreen via the "Restore" window 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // control. 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(pkotwicz): This is a hack. Remove ASAP. http://crbug.com/319048 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->AddObserver(this); 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->window()->AddObserver(this); 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~NativeAppWindowStateDelegate() { 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (window_state_) { 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->RemoveObserver(this); 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->window()->RemoveObserver(this); 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Overridden from ash::wm::WindowStateDelegate. 1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual bool ToggleFullscreen(ash::wm::WindowState* window_state) OVERRIDE { 1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Windows which cannot be maximized should not be fullscreened. 1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(window_state->IsFullscreen() || window_state->CanMaximize()); 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (window_state->IsFullscreen()) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->Restore(); 1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else if (window_state->CanMaximize()) 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->OSFullscreen(); 1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Overridden from ash::wm::WindowStateObserver: 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnPostWindowStateTypeChange( 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::WindowState* window_state, 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::wm::WindowStateType old_type) OVERRIDE { 162a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Since the window state might get set by a window manager, it is possible 163a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // to come here before the application set its |BaseWindow|. 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!window_state->IsFullscreen() && !window_state->IsMinimized() && 165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch app_window_->GetBaseWindow() && 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->GetBaseWindow()->IsFullscreenOrPending()) { 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->Restore(); 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Usually OnNativeWindowChanged() is called when the window bounds are 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // changed as a result of a state type change. Because the change in state 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // type has already occurred, we need to call OnNativeWindowChanged() 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // explicitly. 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->OnNativeWindowChanged(); 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Overridden from aura::WindowObserver: 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->RemoveObserver(this); 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->window()->RemoveObserver(this); 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_ = NULL; 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Not owned. 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppWindow* app_window_; 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::WindowState* window_state_; 1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NativeAppWindowStateDelegate); 1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}; 1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif // USE_ASH 1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ChromeNativeAppWindowViews::ChromeNativeAppWindowViews() 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : is_fullscreen_(false), 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_frame_color_(false), 1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu active_frame_color_(SK_ColorBLACK), 1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu inactive_frame_color_(SK_ColorBLACK) { 1985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ChromeNativeAppWindowViews::~ChromeNativeAppWindowViews() {} 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::OnBeforeWidgetInit( 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::Widget::InitParams* init_params, 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::Widget* widget) {} 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::InitializeDefaultWindow( 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const AppWindow::CreateParams& create_params) { 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string app_name = web_app::GenerateApplicationNameFromExtensionId( 209010d83a9304c5a91596085d917d248abff47903aTorne (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; 213effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch init_params.remove_standard_frame = IsFrameless() || has_frame_color_; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_params.use_system_default_icon = true; 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (create_params.transparent_background) 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) init_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) init_params.keep_on_top = create_params.always_on_top; 21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS) 22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Set up a custom WM_CLASS for app windows. This allows task switchers in 22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // X11 environments to distinguish them from main browser windows. 22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) init_params.wm_class_name = web_app::GetWMClassFromAppName(app_name); 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) init_params.wm_class_class = shell_integration_linux::GetProgramClassName(); 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kX11WindowRoleApp[] = "app"; 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) init_params.wm_role_name = std::string(kX11WindowRoleApp); 22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 22823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) OnBeforeWidgetInit(&init_params, widget()); 22923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->Init(init_params); 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The frame insets are required to resolve the bounds specifications 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // correctly. So we set the window bounds and constraints now. 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Insets frame_insets = GetFrameInsets(); 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect window_bounds = create_params.GetInitialWindowBounds(frame_insets); 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SetContentSizeConstraints(create_params.GetContentMinimumSize(frame_insets), 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_params.GetContentMaximumSize(frame_insets)); 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!window_bounds.IsEmpty()) { 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef apps::AppWindow::BoundsSpecification BoundsSpecification; 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool position_specified = 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_bounds.x() != BoundsSpecification::kUnspecifiedPosition && 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_bounds.y() != BoundsSpecification::kUnspecifiedPosition; 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!position_specified) 24323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->CenterWindow(window_bounds.size()); 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) else 24523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->SetBounds(window_bounds); 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 248a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (IsFrameless() && 249a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch init_params.opacity == views::Widget::InitParams::TRANSLUCENT_WINDOW && 250a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch !create_params.resizable) { 251a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // The given window is most likely not rectangular since it uses 252a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // transparency, has no standard frame and the user cannot resize it using 253a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // the OS supplied methods. Therefore we do not use a shadow for it. 254a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // TODO(skuhne): If we run into an application which should have a shadow 255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // but does not have, a new attribute has to be added. 256a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch wm::SetShadowType(widget()->GetNativeWindow(), wm::SHADOW_TYPE_NONE); 257a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 258a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Register accelarators supported by app windows. 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(jeremya/stevenjb): should these be registered for panels too? 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::FocusManager* focus_manager = GetFocusManager(); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::map<ui::Accelerator, int>& accelerator_table = 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetAcceleratorTable(); 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const bool is_kiosk_app_mode = chrome::IsRunningInForcedAppMode(); 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ensures that kiosk mode accelerators are enabled when in kiosk mode (to be 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // future proof). This is needed because GetAcceleratorTable() uses a static 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to store data and only checks kiosk mode once. If a platform app is 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // launched before kiosk mode starts, the kiosk accelerators will not be 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // registered. This DCHECK catches the case. 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!is_kiosk_app_mode || 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) accelerator_table.size() == 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowAcceleratorMap) + 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowKioskAppModeAcceleratorMap)); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::map<ui::Accelerator, int>::const_iterator iter = 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) accelerator_table.begin(); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != accelerator_table.end(); ++iter) { 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (is_kiosk_app_mode && !chrome::IsCommandAllowedInAppMode(iter->second)) 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) focus_manager->RegisterAccelerator( 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter->first, ui::AcceleratorManager::kNormalPriority, this); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::InitializePanelWindow( 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const AppWindow::CreateParams& create_params) { 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Widget::InitParams params(views::Widget::InitParams::TYPE_PANEL); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.delegate = this; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect initial_window_bounds = 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_params.GetInitialWindowBounds(gfx::Insets()); 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) preferred_size_ = gfx::Size(initial_window_bounds.width(), 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) initial_window_bounds.height()); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (preferred_size_.width() == 0) 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_width(kDefaultPanelWidth); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (preferred_size_.width() < kMinPanelWidth) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_width(kMinPanelWidth); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (preferred_size_.height() == 0) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_height(kDefaultPanelHeight); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (preferred_size_.height() < kMinPanelHeight) 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_height(kMinPanelHeight); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ash::Shell::HasInstance()) { 307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Open a new panel on the target root. 3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* target = ash::Shell::GetTargetRootWindow(); 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.bounds = ash::ScreenUtil::ConvertRectToScreen( 310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) target, gfx::Rect(preferred_size_)); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.bounds = gfx::Rect(preferred_size_); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.bounds = gfx::Rect(preferred_size_); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 31723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->Init(params); 31823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->set_focus_on_creation(create_params.focused); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#if defined(USE_ASH) 321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (create_params.state == ui::SHOW_STATE_DETACHED) { 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect window_bounds(initial_window_bounds.x(), 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) initial_window_bounds.y(), 324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) preferred_size_.width(), 325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) preferred_size_.height()); 326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) aura::Window* native_window = GetNativeWindow(); 32768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ash::wm::GetWindowState(native_window)->set_panel_attached(false); 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::client::ParentWindowWithContext(native_window, 3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) native_window->GetRootWindow(), 3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) native_window->GetBoundsInScreen()); 33123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->SetBounds(window_bounds); 332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#else 334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // TODO(stevenjb): NativeAppWindow panels need to be implemented for other 335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // platforms. 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuviews::NonClientFrameView* 3405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuChromeNativeAppWindowViews::CreateStandardDesktopAppFrame() { 3415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return views::WidgetDelegateView::CreateNonClientFrameView(widget()); 3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)apps::AppWindowFrameView* 3455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuChromeNativeAppWindowViews::CreateNonStandardAppFrame() { 3465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu apps::AppWindowFrameView* frame = 3475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new apps::AppWindowFrameView(widget(), 3485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu this, 3495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu has_frame_color_, 3505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu active_frame_color_, 3515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu inactive_frame_color_); 3525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu frame->Init(); 3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(USE_ASH) 3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // For Aura windows on the Ash desktop the sizes are different and the user 3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // can resize the window from slightly outside the bounds as well. 35623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (chrome::IsNativeWindowInAsh(widget()->GetNativeWindow())) { 3575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu frame->SetResizeSizes(ash::kResizeInsideBoundsSize, 3585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ash::kResizeOutsideBoundsSize, 3595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ash::kResizeAreaCornerSize); 3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 3625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if !defined(OS_CHROMEOS) 3645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // For non-Ash windows, install an easy resize window targeter, which ensures 3655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // that the root window (not the app) receives mouse events on the edges. 3665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (chrome::GetHostDesktopTypeForNativeWindow(widget()->GetNativeWindow()) != 3675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu chrome::HOST_DESKTOP_TYPE_ASH) { 3685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu aura::Window* window = widget()->GetNativeWindow(); 3695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int resize_inside = frame->resize_inside_bounds_size(); 3705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Insets inset( 3715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu resize_inside, resize_inside, resize_inside, resize_inside); 3725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Add the EasyResizeWindowTargeter on the window, not its root window. The 3735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // root window does not have a delegate, which is needed to handle the event 3745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // in Linux. 3755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window->SetEventTargeter(scoped_ptr<ui::EventTargeter>( 3765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new wm::EasyResizeWindowTargeter(window, inset, inset))); 3775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 3785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif 3795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return frame; 3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// ui::BaseWindow implementation. 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 385010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)gfx::Rect ChromeNativeAppWindowViews::GetRestoredBounds() const { 386010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(USE_ASH) 387010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect* bounds = widget()->GetNativeWindow()->GetProperty( 388010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ash::kRestoreBoundsOverrideKey); 389010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (bounds && !bounds->IsEmpty()) 390010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return *bounds; 391010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif 392010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return widget()->GetRestoredBounds(); 393010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 394010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ui::WindowShowState ChromeNativeAppWindowViews::GetRestoredState() const { 396010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if !defined(USE_ASH) 397b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (IsMaximized()) 398b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return ui::SHOW_STATE_MAXIMIZED; 399010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsFullscreen()) 400b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return ui::SHOW_STATE_FULLSCREEN; 401010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#else 402b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Use kRestoreShowStateKey in case a window is minimized/hidden. 40323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::WindowShowState restore_state = widget()->GetNativeWindow()->GetProperty( 40423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) aura::client::kRestoreShowStateKey); 405010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (widget()->GetNativeWindow()->GetProperty( 406010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ash::kRestoreBoundsOverrideKey)) { 407010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If an override is given, we use that restore state (after filtering). 408010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) restore_state = widget()->GetNativeWindow()->GetProperty( 409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ash::kRestoreShowStateOverrideKey); 410010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 411010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Otherwise first normal states are checked. 412010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsMaximized()) 413010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ui::SHOW_STATE_MAXIMIZED; 414010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsFullscreen()) { 415010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (immersive_fullscreen_controller_.get() && 416010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) immersive_fullscreen_controller_->IsEnabled()) { 417010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Restore windows which were previously in immersive fullscreen to 418010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // maximized. Restoring the window to a different fullscreen type 419010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // makes for a bad experience. 420010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ui::SHOW_STATE_MAXIMIZED; 421010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 422010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ui::SHOW_STATE_FULLSCREEN; 423010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 424010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 425ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Whitelist states to return so that invalid and transient states 426ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // are not saved and used to restore windows when they are recreated. 427ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch switch (restore_state) { 428ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_NORMAL: 429ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_MAXIMIZED: 430ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_FULLSCREEN: 431ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_DETACHED: 432ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return restore_state; 433ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 434ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_DEFAULT: 435ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_MINIMIZED: 436ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_INACTIVE: 437ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_END: 438ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return ui::SHOW_STATE_NORMAL; 439ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 440010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif // !defined(USE_ASH) 441b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return ui::SHOW_STATE_NORMAL; 442b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 443b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::IsAlwaysOnTop() const { 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (app_window()->window_type_is_panel()) { 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(USE_ASH) 44723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return ash::wm::GetWindowState(widget()->GetNativeWindow()) 44823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ->panel_attached(); 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 45323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return widget()->IsAlwaysOnTop(); 4544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// views::ContextMenuController implementation. 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::ShowContextMenuForView( 460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::View* source, 461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const gfx::Point& p, 462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::MenuSourceType source_type) { 463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(USE_ASH) && defined(OS_CHROMEOS) 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<ui::MenuModel> model = 465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateMultiUserContextMenu(app_window()->GetNativeWindow()); 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!model.get()) 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Only show context menu if point is in caption. 470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point point_in_view_coords(p); 47123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) views::View::ConvertPointFromScreen(widget()->non_client_view(), 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &point_in_view_coords); 47323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int hit_test = 47423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->non_client_view()->NonClientHitTest(point_in_view_coords); 475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (hit_test == HTCAPTION) { 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) menu_runner_.reset(new views::MenuRunner(model.get())); 4775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (menu_runner_->RunMenuAt(source->GetWidget(), 4785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NULL, 4795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect(p, gfx::Size(0, 0)), 4805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::MENU_ANCHOR_TOPLEFT, 4815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu source_type, 4825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::MenuRunner::HAS_MNEMONICS | 4835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::MenuRunner::CONTEXT_MENU) == 4845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::MenuRunner::MENU_DELETED) { 485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 4865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// views::WidgetDelegate implementation. 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)gfx::ImageSkia ChromeNativeAppWindowViews::GetWindowAppIcon() { 494a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Image app_icon = app_window()->app_icon(); 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (app_icon.IsEmpty()) 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetWindowIcon(); 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *app_icon.ToImageSkia(); 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)gfx::ImageSkia ChromeNativeAppWindowViews::GetWindowIcon() { 502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::WebContents* web_contents = app_window()->web_contents(); 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (web_contents) { 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconTabHelper* favicon_tab_helper = 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconTabHelper::FromWebContents(web_contents); 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Image app_icon = favicon_tab_helper->GetFavicon(); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!app_icon.IsEmpty()) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *app_icon.ToImageSkia(); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::ImageSkia(); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 513a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)views::NonClientFrameView* ChromeNativeAppWindowViews::CreateNonClientFrameView( 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Widget* widget) { 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH) 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (chrome::IsNativeViewInAsh(widget->GetNativeView())) { 517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Set the delegate now because CustomFrameViewAsh sets the 518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // WindowStateDelegate if one is not already set. 519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ash::wm::GetWindowState(GetNativeWindow())->SetDelegate( 520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<ash::wm::WindowStateDelegate>( 521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new NativeAppWindowStateDelegate(app_window(), this)).Pass()); 522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (app_window()->window_type_is_panel()) { 524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::PanelFrameView::FrameType frame_type = IsFrameless() ? 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ash::PanelFrameView::FRAME_NONE : ash::PanelFrameView::FRAME_ASH; 526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::NonClientFrameView* frame_view = 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new ash::PanelFrameView(widget, frame_type); 528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) frame_view->set_context_menu_controller(this); 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return frame_view; 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (IsFrameless()) 5335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return CreateNonStandardAppFrame(); 5345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ash::CustomFrameViewAsh* custom_frame_view = 5365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new ash::CustomFrameViewAsh(widget); 5375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if defined(OS_CHROMEOS) 5385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Non-frameless app windows can be put into immersive fullscreen. 5395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // TODO(pkotwicz): Investigate if immersive fullscreen can be enabled for 5405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Windows Ash. 5415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu immersive_fullscreen_controller_.reset( 5425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new ash::ImmersiveFullscreenController()); 5435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu custom_frame_view->InitImmersiveFullscreenControllerForView( 5445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu immersive_fullscreen_controller_.get()); 5455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif 5465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu custom_frame_view->GetHeaderView()->set_context_menu_controller(this); 5475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return custom_frame_view; 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return (IsFrameless() || has_frame_color_) ? 551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateNonStandardAppFrame() : CreateStandardDesktopAppFrame(); 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::WidgetHasHitTestMask() const { 555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return shape_ != NULL; 5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::GetWidgetHitTestMask(gfx::Path* mask) const { 559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shape_->getBoundaryPath(mask); 5603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// views::View implementation. 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size ChromeNativeAppWindowViews::GetPreferredSize() const { 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!preferred_size_.IsEmpty()) 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return preferred_size_; 567a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NativeAppWindowViews::GetPreferredSize(); 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::AcceleratorPressed( 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ui::Accelerator& accelerator) { 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::map<ui::Accelerator, int>& accelerator_table = 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetAcceleratorTable(); 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<ui::Accelerator, int>::const_iterator iter = 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) accelerator_table.find(accelerator); 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(iter != accelerator_table.end()); 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int command_id = iter->second; 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (command_id) { 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case IDC_CLOSE_WINDOW: 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Close(); 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_ZOOM_MINUS: 583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_page_zoom::Zoom(web_view()->GetWebContents(), 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::PAGE_ZOOM_OUT); 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_ZOOM_NORMAL: 587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_page_zoom::Zoom(web_view()->GetWebContents(), 5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::PAGE_ZOOM_RESET); 5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_ZOOM_PLUS: 591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_page_zoom::Zoom(web_view()->GetWebContents(), 5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::PAGE_ZOOM_IN); 5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "Unknown accelerator sent to app window."; 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 597a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NativeAppWindowViews::AcceleratorPressed(accelerator); 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NativeAppWindow implementation. 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::SetFullscreen(int fullscreen_types) { 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fullscreen not supported by panels. 604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (app_window()->window_type_is_panel()) 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_fullscreen_ = (fullscreen_types != AppWindow::FULLSCREEN_TYPE_NONE); 60723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->SetFullscreen(is_fullscreen_); 608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(USE_ASH) 610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (immersive_fullscreen_controller_.get()) { 611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |immersive_fullscreen_controller_| should only be set if immersive 612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // fullscreen is the fullscreen type used by the OS. 613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) immersive_fullscreen_controller_->SetEnabled( 6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ImmersiveFullscreenController::WINDOW_TYPE_PACKAGED_APP, 6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (fullscreen_types & AppWindow::FULLSCREEN_TYPE_OS) != 0); 616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Autohide the shelf instead of hiding the shelf completely when only in 617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // OS fullscreen. 618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::WindowState* window_state = 61923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ash::wm::GetWindowState(widget()->GetNativeWindow()); 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_state->set_hide_shelf_when_fullscreen(fullscreen_types != 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppWindow::FULLSCREEN_TYPE_OS); 622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(ash::Shell::HasInstance()); 623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::Shell::GetInstance()->UpdateShelfVisibility(); 624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(jeremya) we need to call RenderViewHost::ExitFullscreen() if we 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ever drop the window out of fullscreen in response to something that 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // wasn't the app calling webkitCancelFullScreen(). 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::IsFullscreenOrPending() const { 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return is_fullscreen_; 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 636a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::IsDetached() const { 637a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!app_window()->window_type_is_panel()) 638b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 639b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#if defined(USE_ASH) 64023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return !ash::wm::GetWindowState(widget()->GetNativeWindow()) 641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ->panel_attached(); 642b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#else 643b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 644b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif 645b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 646b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::UpdateBadgeIcon() { 6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Image* icon = NULL; 649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!app_window()->badge_icon().IsEmpty()) { 650a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) icon = &app_window()->badge_icon(); 6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // chrome::DrawTaskbarDecoration can do interesting things with non-square 6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // bitmaps. 6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(benwells): Refactor chrome::DrawTaskbarDecoration to not be avatar 6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // specific, and lift this restriction. 6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (icon->Width() != icon->Height()) { 6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << "Attempt to set a non-square badge; request ignored."; 6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::DrawTaskbarDecoration(GetNativeWindow(), icon); 6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::UpdateShape(scoped_ptr<SkRegion> region) { 6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool had_shape = shape_; 665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shape_ = region.Pass(); 666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 66723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) aura::Window* native_window = widget()->GetNativeWindow(); 6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (shape_) { 669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) widget()->SetShape(new SkRegion(*shape_)); 6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!had_shape) { 6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>( 6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new ShapedAppWindowTargeter(native_window, this))); 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 67523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->SetShape(NULL); 6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (had_shape) 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>()); 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::HasFrameColor() const { 682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return has_frame_color_; 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSkColor ChromeNativeAppWindowViews::ActiveFrameColor() const { 6865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return active_frame_color_; 6875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 6885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 6895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSkColor ChromeNativeAppWindowViews::InactiveFrameColor() const { 6905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return inactive_frame_color_; 6915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 6924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 693a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// NativeAppWindowViews implementation. 6944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::InitializeWindow( 696a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AppWindow* app_window, 697a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const AppWindow::CreateParams& create_params) { 69823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(widget()); 699a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_frame_color_ = create_params.has_frame_color; 7005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu active_frame_color_ = create_params.active_frame_color; 7015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu inactive_frame_color_ = create_params.inactive_frame_color; 702a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (create_params.window_type == AppWindow::WINDOW_TYPE_PANEL || 703a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_params.window_type == AppWindow::WINDOW_TYPE_V1_PANEL) { 704a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) InitializePanelWindow(create_params); 705a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) InitializeDefaultWindow(create_params); 707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension_keybinding_registry_.reset(new ExtensionKeybindingRegistryViews( 709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile::FromBrowserContext(app_window->browser_context()), 71023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) widget()->GetFocusManager(), 711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY, 712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL)); 713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 714