1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/views/frame/browser_frame_aura.h" 6 7 #include "base/command_line.h" 8 #include "chrome/app/chrome_command_ids.h" 9 #include "chrome/browser/ui/views/frame/browser_view.h" 10 #include "grit/chromium_strings.h" 11 #include "grit/generated_resources.h" 12 #include "ui/aura/client/aura_constants.h" 13 #include "ui/aura/window.h" 14 #include "ui/aura/window_observer.h" 15 #include "ui/base/hit_test.h" 16 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/gfx/font.h" 18 #include "ui/views/view.h" 19 20 #if defined(USE_ASH) 21 #include "ash/wm/window_util.h" 22 #include "chrome/browser/ui/ash/ash_init.h" 23 #endif 24 25 #if !defined(OS_CHROMEOS) 26 #include "chrome/browser/ui/views/frame/desktop_browser_frame_aura.h" 27 #endif 28 29 using aura::Window; 30 31 //////////////////////////////////////////////////////////////////////////////// 32 // BrowserFrameAura::WindowPropertyWatcher 33 34 class BrowserFrameAura::WindowPropertyWatcher : public aura::WindowObserver { 35 public: 36 explicit WindowPropertyWatcher(BrowserFrameAura* browser_frame_aura, 37 BrowserFrame* browser_frame) 38 : browser_frame_aura_(browser_frame_aura), 39 browser_frame_(browser_frame) {} 40 41 virtual void OnWindowPropertyChanged(aura::Window* window, 42 const void* key, 43 intptr_t old) OVERRIDE { 44 if (key != aura::client::kShowStateKey) 45 return; 46 47 ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old); 48 ui::WindowShowState new_state = 49 window->GetProperty(aura::client::kShowStateKey); 50 51 // Allow the frame to be replaced when entering or exiting the maximized 52 // state. 53 if (browser_frame_->non_client_view() && 54 browser_frame_aura_->browser_view()->browser()->is_app() && 55 (old_state == ui::SHOW_STATE_MAXIMIZED || 56 new_state == ui::SHOW_STATE_MAXIMIZED)) { 57 // Defer frame layout when replacing the frame. Layout will occur when the 58 // window's bounds are updated. The window maximize/restore animations 59 // clone the window's layers and rely on the subsequent layout to set 60 // the layer sizes. 61 // If the window is minimized, the frame view needs to be updated via 62 // an OnBoundsChanged event so that the frame will change its size 63 // properly. 64 browser_frame_->non_client_view()->UpdateFrame( 65 old_state == ui::SHOW_STATE_MINIMIZED); 66 } 67 } 68 69 virtual void OnWindowBoundsChanged(aura::Window* window, 70 const gfx::Rect& old_bounds, 71 const gfx::Rect& new_bounds) OVERRIDE { 72 // Don't do anything if we don't have our non-client view yet. 73 if (!browser_frame_->non_client_view()) 74 return; 75 76 // If the window just moved to the top of the screen, or just moved away 77 // from it, invoke Layout() so the header size can change. 78 if ((old_bounds.y() == 0 && new_bounds.y() != 0) || 79 (old_bounds.y() != 0 && new_bounds.y() == 0)) 80 browser_frame_->non_client_view()->Layout(); 81 } 82 83 private: 84 BrowserFrameAura* browser_frame_aura_; 85 BrowserFrame* browser_frame_; 86 87 DISALLOW_COPY_AND_ASSIGN(WindowPropertyWatcher); 88 }; 89 90 /////////////////////////////////////////////////////////////////////////////// 91 // BrowserFrameAura, public: 92 93 // static 94 const char BrowserFrameAura::kWindowName[] = "BrowserFrameAura"; 95 96 BrowserFrameAura::BrowserFrameAura(BrowserFrame* browser_frame, 97 BrowserView* browser_view) 98 : views::NativeWidgetAura(browser_frame), 99 browser_view_(browser_view), 100 window_property_watcher_(new WindowPropertyWatcher(this, browser_frame)) { 101 GetNativeWindow()->SetName(kWindowName); 102 GetNativeWindow()->AddObserver(window_property_watcher_.get()); 103 #if defined(USE_ASH) 104 // Turn on auto window management if we don't need an explicit bounds. 105 // This way the requested bounds are honored. 106 if (!browser_view->browser()->bounds_overridden() && 107 !browser_view->browser()->is_session_restore()) 108 SetWindowAutoManaged(); 109 #endif 110 } 111 112 /////////////////////////////////////////////////////////////////////////////// 113 // BrowserFrameAura, views::NativeWidgetAura overrides: 114 115 void BrowserFrameAura::OnWindowDestroying() { 116 // Window is destroyed before our destructor is called, so clean up our 117 // observer here. 118 GetNativeWindow()->RemoveObserver(window_property_watcher_.get()); 119 views::NativeWidgetAura::OnWindowDestroying(); 120 } 121 122 void BrowserFrameAura::OnWindowTargetVisibilityChanged(bool visible) { 123 if (visible) { 124 // Once the window has been shown we know the requested bounds 125 // (if provided) have been honored and we can switch on window management. 126 SetWindowAutoManaged(); 127 } 128 views::NativeWidgetAura::OnWindowTargetVisibilityChanged(visible); 129 } 130 131 //////////////////////////////////////////////////////////////////////////////// 132 // BrowserFrameAura, NativeBrowserFrame implementation: 133 134 views::NativeWidget* BrowserFrameAura::AsNativeWidget() { 135 return this; 136 } 137 138 const views::NativeWidget* BrowserFrameAura::AsNativeWidget() const { 139 return this; 140 } 141 142 bool BrowserFrameAura::UsesNativeSystemMenu() const { 143 return false; 144 } 145 146 int BrowserFrameAura::GetMinimizeButtonOffset() const { 147 return 0; 148 } 149 150 void BrowserFrameAura::TabStripDisplayModeChanged() { 151 } 152 153 //////////////////////////////////////////////////////////////////////////////// 154 // BrowserFrame, public: 155 156 // static 157 const gfx::Font& BrowserFrame::GetTitleFont() { 158 static gfx::Font* title_font = new gfx::Font; 159 return *title_font; 160 } 161 162 //////////////////////////////////////////////////////////////////////////////// 163 // NativeBrowserFrame, public: 164 165 // static 166 NativeBrowserFrame* NativeBrowserFrame::CreateNativeBrowserFrame( 167 BrowserFrame* browser_frame, 168 BrowserView* browser_view) { 169 #if !defined(OS_CHROMEOS) 170 if ( 171 #if defined(USE_ASH) 172 !chrome::ShouldOpenAshOnStartup() && 173 #endif 174 browser_view->browser()-> 175 host_desktop_type() == chrome::HOST_DESKTOP_TYPE_NATIVE) 176 return new DesktopBrowserFrameAura(browser_frame, browser_view); 177 #endif 178 return new BrowserFrameAura(browser_frame, browser_view); 179 } 180 181 /////////////////////////////////////////////////////////////////////////////// 182 // BrowserFrameAura, private: 183 184 BrowserFrameAura::~BrowserFrameAura() { 185 } 186 187 void BrowserFrameAura::SetWindowAutoManaged() { 188 #if defined(USE_ASH) 189 if (browser_view_->browser()->type() != Browser::TYPE_POPUP || 190 browser_view_->browser()->is_app()) 191 ash::wm::SetWindowPositionManaged(GetNativeWindow(), true); 192 #endif 193 } 194