| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "apps/shell_window.h" | 5 #include "apps/app_window.h" |
| 6 | 6 |
| 7 #include "apps/shell_window_geometry_cache.h" | 7 #include "apps/app_window_geometry_cache.h" |
| 8 #include "apps/shell_window_registry.h" | 8 #include "apps/app_window_registry.h" |
| 9 #include "apps/ui/native_app_window.h" | 9 #include "apps/ui/native_app_window.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
| 15 #include "chrome/browser/extensions/extension_web_contents_observer.h" | 15 #include "chrome/browser/extensions/extension_web_contents_observer.h" |
| 16 #include "chrome/browser/extensions/suggest_permission_util.h" | 16 #include "chrome/browser/extensions/suggest_permission_util.h" |
| 17 #include "chrome/browser/lifetime/application_lifetime.h" | 17 #include "chrome/browser/lifetime/application_lifetime.h" |
| 18 #include "chrome/common/chrome_switches.h" | 18 #include "chrome/common/chrome_switches.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 using extensions::APIPermission; | 50 using extensions::APIPermission; |
| 51 using web_modal::WebContentsModalDialogHost; | 51 using web_modal::WebContentsModalDialogHost; |
| 52 using web_modal::WebContentsModalDialogManager; | 52 using web_modal::WebContentsModalDialogManager; |
| 53 | 53 |
| 54 namespace { | 54 namespace { |
| 55 | 55 |
| 56 const int kDefaultWidth = 512; | 56 const int kDefaultWidth = 512; |
| 57 const int kDefaultHeight = 384; | 57 const int kDefaultHeight = 384; |
| 58 | 58 |
| 59 bool IsFullscreen(int fullscreen_types) { | 59 bool IsFullscreen(int fullscreen_types) { |
| 60 return fullscreen_types != apps::ShellWindow::FULLSCREEN_TYPE_NONE; | 60 return fullscreen_types != apps::AppWindow::FULLSCREEN_TYPE_NONE; |
| 61 } | 61 } |
| 62 | 62 |
| 63 } // namespace | 63 } // namespace |
| 64 | 64 |
| 65 namespace apps { | 65 namespace apps { |
| 66 | 66 |
| 67 ShellWindow::SizeConstraints::SizeConstraints() | 67 AppWindow::SizeConstraints::SizeConstraints() |
| 68 : maximum_size_(kUnboundedSize, kUnboundedSize) { | 68 : maximum_size_(kUnboundedSize, kUnboundedSize) {} |
| 69 } | |
| 70 | 69 |
| 71 ShellWindow::SizeConstraints::SizeConstraints(const gfx::Size& min_size, | 70 AppWindow::SizeConstraints::SizeConstraints(const gfx::Size& min_size, |
| 72 const gfx::Size& max_size) | 71 const gfx::Size& max_size) |
| 73 : minimum_size_(min_size), | 72 : minimum_size_(min_size), maximum_size_(max_size) {} |
| 74 maximum_size_(max_size) { | |
| 75 } | |
| 76 | 73 |
| 77 ShellWindow::SizeConstraints::~SizeConstraints() {} | 74 AppWindow::SizeConstraints::~SizeConstraints() {} |
| 78 | 75 |
| 79 gfx::Size ShellWindow::SizeConstraints::ClampSize(gfx::Size size) const { | 76 gfx::Size AppWindow::SizeConstraints::ClampSize(gfx::Size size) const { |
| 80 const gfx::Size max_size = GetMaximumSize(); | 77 const gfx::Size max_size = GetMaximumSize(); |
| 81 if (max_size.width() != kUnboundedSize) | 78 if (max_size.width() != kUnboundedSize) |
| 82 size.set_width(std::min(size.width(), GetMaximumSize().width())); | 79 size.set_width(std::min(size.width(), GetMaximumSize().width())); |
| 83 if (max_size.height() != kUnboundedSize) | 80 if (max_size.height() != kUnboundedSize) |
| 84 size.set_height(std::min(size.height(), GetMaximumSize().height())); | 81 size.set_height(std::min(size.height(), GetMaximumSize().height())); |
| 85 size.SetToMax(GetMinimumSize()); | 82 size.SetToMax(GetMinimumSize()); |
| 86 return size; | 83 return size; |
| 87 } | 84 } |
| 88 | 85 |
| 89 bool ShellWindow::SizeConstraints::HasMinimumSize() const { | 86 bool AppWindow::SizeConstraints::HasMinimumSize() const { |
| 90 return GetMinimumSize().width() != kUnboundedSize || | 87 return GetMinimumSize().width() != kUnboundedSize || |
| 91 GetMinimumSize().height() != kUnboundedSize; | 88 GetMinimumSize().height() != kUnboundedSize; |
| 92 } | 89 } |
| 93 | 90 |
| 94 bool ShellWindow::SizeConstraints::HasMaximumSize() const { | 91 bool AppWindow::SizeConstraints::HasMaximumSize() const { |
| 95 const gfx::Size max_size = GetMaximumSize(); | 92 const gfx::Size max_size = GetMaximumSize(); |
| 96 return max_size.width() != kUnboundedSize || | 93 return max_size.width() != kUnboundedSize || |
| 97 max_size.height() != kUnboundedSize; | 94 max_size.height() != kUnboundedSize; |
| 98 } | 95 } |
| 99 | 96 |
| 100 bool ShellWindow::SizeConstraints::HasFixedSize() const { | 97 bool AppWindow::SizeConstraints::HasFixedSize() const { |
| 101 return !GetMinimumSize().IsEmpty() && GetMinimumSize() == GetMaximumSize(); | 98 return !GetMinimumSize().IsEmpty() && GetMinimumSize() == GetMaximumSize(); |
| 102 } | 99 } |
| 103 | 100 |
| 104 gfx::Size ShellWindow::SizeConstraints::GetMinimumSize() const { | 101 gfx::Size AppWindow::SizeConstraints::GetMinimumSize() const { |
| 105 return minimum_size_; | 102 return minimum_size_; |
| 106 } | 103 } |
| 107 | 104 |
| 108 gfx::Size ShellWindow::SizeConstraints::GetMaximumSize() const { | 105 gfx::Size AppWindow::SizeConstraints::GetMaximumSize() const { |
| 109 return gfx::Size( | 106 return gfx::Size( |
| 110 maximum_size_.width() == kUnboundedSize ? | 107 maximum_size_.width() == kUnboundedSize |
| 111 kUnboundedSize : | 108 ? kUnboundedSize |
| 112 std::max(maximum_size_.width(), minimum_size_.width()), | 109 : std::max(maximum_size_.width(), minimum_size_.width()), |
| 113 maximum_size_.height() == kUnboundedSize ? | 110 maximum_size_.height() == kUnboundedSize |
| 114 kUnboundedSize : | 111 ? kUnboundedSize |
| 115 std::max(maximum_size_.height(), minimum_size_.height())); | 112 : std::max(maximum_size_.height(), minimum_size_.height())); |
| 116 } | 113 } |
| 117 | 114 |
| 118 void ShellWindow::SizeConstraints::set_minimum_size(const gfx::Size& min_size) { | 115 void AppWindow::SizeConstraints::set_minimum_size(const gfx::Size& min_size) { |
| 119 minimum_size_ = min_size; | 116 minimum_size_ = min_size; |
| 120 } | 117 } |
| 121 | 118 |
| 122 void ShellWindow::SizeConstraints::set_maximum_size(const gfx::Size& max_size) { | 119 void AppWindow::SizeConstraints::set_maximum_size(const gfx::Size& max_size) { |
| 123 maximum_size_ = max_size; | 120 maximum_size_ = max_size; |
| 124 } | 121 } |
| 125 | 122 |
| 126 ShellWindow::CreateParams::CreateParams() | 123 AppWindow::CreateParams::CreateParams() |
| 127 : window_type(ShellWindow::WINDOW_TYPE_DEFAULT), | 124 : window_type(AppWindow::WINDOW_TYPE_DEFAULT), |
| 128 frame(ShellWindow::FRAME_CHROME), | 125 frame(AppWindow::FRAME_CHROME), |
| 129 transparent_background(false), | 126 transparent_background(false), |
| 130 bounds(INT_MIN, INT_MIN, 0, 0), | 127 bounds(INT_MIN, INT_MIN, 0, 0), |
| 131 creator_process_id(0), | 128 creator_process_id(0), |
| 132 state(ui::SHOW_STATE_DEFAULT), | 129 state(ui::SHOW_STATE_DEFAULT), |
| 133 hidden(false), | 130 hidden(false), |
| 134 resizable(true), | 131 resizable(true), |
| 135 focused(true), | 132 focused(true), |
| 136 always_on_top(false) {} | 133 always_on_top(false) {} |
| 137 | 134 |
| 138 ShellWindow::CreateParams::~CreateParams() {} | 135 AppWindow::CreateParams::~CreateParams() {} |
| 139 | 136 |
| 140 ShellWindow::Delegate::~Delegate() {} | 137 AppWindow::Delegate::~Delegate() {} |
| 141 | 138 |
| 142 ShellWindow::ShellWindow(BrowserContext* context, | 139 AppWindow::AppWindow(BrowserContext* context, |
| 143 Delegate* delegate, | 140 Delegate* delegate, |
| 144 const extensions::Extension* extension) | 141 const extensions::Extension* extension) |
| 145 : browser_context_(context), | 142 : browser_context_(context), |
| 146 extension_(extension), | 143 extension_(extension), |
| 147 extension_id_(extension->id()), | 144 extension_id_(extension->id()), |
| 148 window_type_(WINDOW_TYPE_DEFAULT), | 145 window_type_(WINDOW_TYPE_DEFAULT), |
| 149 delegate_(delegate), | 146 delegate_(delegate), |
| 150 image_loader_ptr_factory_(this), | 147 image_loader_ptr_factory_(this), |
| 151 fullscreen_types_(FULLSCREEN_TYPE_NONE), | 148 fullscreen_types_(FULLSCREEN_TYPE_NONE), |
| 152 show_on_first_paint_(false), | 149 show_on_first_paint_(false), |
| 153 first_paint_complete_(false), | 150 first_paint_complete_(false), |
| 154 cached_always_on_top_(false) { | 151 cached_always_on_top_(false) { |
| 155 extensions::ExtensionsBrowserClient* client = | 152 extensions::ExtensionsBrowserClient* client = |
| 156 extensions::ExtensionsBrowserClient::Get(); | 153 extensions::ExtensionsBrowserClient::Get(); |
| 157 CHECK(!client->IsGuestSession(context) || context->IsOffTheRecord()) | 154 CHECK(!client->IsGuestSession(context) || context->IsOffTheRecord()) |
| 158 << "Only off the record window may be opened in the guest mode."; | 155 << "Only off the record window may be opened in the guest mode."; |
| 159 } | 156 } |
| 160 | 157 |
| 161 void ShellWindow::Init(const GURL& url, | 158 void AppWindow::Init(const GURL& url, |
| 162 ShellWindowContents* shell_window_contents, | 159 AppWindowContents* app_window_contents, |
| 163 const CreateParams& params) { | 160 const CreateParams& params) { |
| 164 // Initialize the render interface and web contents | 161 // Initialize the render interface and web contents |
| 165 shell_window_contents_.reset(shell_window_contents); | 162 app_window_contents_.reset(app_window_contents); |
| 166 shell_window_contents_->Initialize(browser_context(), url); | 163 app_window_contents_->Initialize(browser_context(), url); |
| 167 WebContents* web_contents = shell_window_contents_->GetWebContents(); | 164 WebContents* web_contents = app_window_contents_->GetWebContents(); |
| 168 if (CommandLine::ForCurrentProcess()->HasSwitch( | 165 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 169 switches::kEnableAppsShowOnFirstPaint)) { | 166 switches::kEnableAppsShowOnFirstPaint)) { |
| 170 content::WebContentsObserver::Observe(web_contents); | 167 content::WebContentsObserver::Observe(web_contents); |
| 171 } | 168 } |
| 172 delegate_->InitWebContents(web_contents); | 169 delegate_->InitWebContents(web_contents); |
| 173 WebContentsModalDialogManager::CreateForWebContents(web_contents); | 170 WebContentsModalDialogManager::CreateForWebContents(web_contents); |
| 174 extensions::ExtensionWebContentsObserver::CreateForWebContents(web_contents); | 171 extensions::ExtensionWebContentsObserver::CreateForWebContents(web_contents); |
| 175 | 172 |
| 176 web_contents->SetDelegate(this); | 173 web_contents->SetDelegate(this); |
| 177 WebContentsModalDialogManager::FromWebContents(web_contents)-> | 174 WebContentsModalDialogManager::FromWebContents(web_contents) |
| 178 SetDelegate(this); | 175 ->SetDelegate(this); |
| 179 extensions::SetViewType(web_contents, extensions::VIEW_TYPE_APP_SHELL); | 176 extensions::SetViewType(web_contents, extensions::VIEW_TYPE_APP_SHELL); |
| 180 | 177 |
| 181 // Initialize the window | 178 // Initialize the window |
| 182 CreateParams new_params = LoadDefaultsAndConstrain(params); | 179 CreateParams new_params = LoadDefaultsAndConstrain(params); |
| 183 window_type_ = new_params.window_type; | 180 window_type_ = new_params.window_type; |
| 184 window_key_ = new_params.window_key; | 181 window_key_ = new_params.window_key; |
| 185 size_constraints_ = SizeConstraints(new_params.minimum_size, | 182 size_constraints_ = |
| 186 new_params.maximum_size); | 183 SizeConstraints(new_params.minimum_size, new_params.maximum_size); |
| 187 | 184 |
| 188 // Windows cannot be always-on-top in fullscreen mode for security reasons. | 185 // Windows cannot be always-on-top in fullscreen mode for security reasons. |
| 189 cached_always_on_top_ = new_params.always_on_top; | 186 cached_always_on_top_ = new_params.always_on_top; |
| 190 if (new_params.state == ui::SHOW_STATE_FULLSCREEN) | 187 if (new_params.state == ui::SHOW_STATE_FULLSCREEN) |
| 191 new_params.always_on_top = false; | 188 new_params.always_on_top = false; |
| 192 | 189 |
| 193 native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params)); | 190 native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params)); |
| 194 | 191 |
| 195 if (!new_params.hidden) { | 192 if (!new_params.hidden) { |
| 196 // Panels are not activated by default. | 193 // Panels are not activated by default. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 211 // about it in case it has any setup to do to make the renderer appear | 208 // about it in case it has any setup to do to make the renderer appear |
| 212 // properly. In particular, on Windows, the view's clickthrough region needs | 209 // properly. In particular, on Windows, the view's clickthrough region needs |
| 213 // to be set. | 210 // to be set. |
| 214 extensions::ExtensionsBrowserClient* client = | 211 extensions::ExtensionsBrowserClient* client = |
| 215 extensions::ExtensionsBrowserClient::Get(); | 212 extensions::ExtensionsBrowserClient::Get(); |
| 216 registrar_.Add(this, | 213 registrar_.Add(this, |
| 217 chrome::NOTIFICATION_EXTENSION_UNLOADED, | 214 chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 218 content::Source<content::BrowserContext>( | 215 content::Source<content::BrowserContext>( |
| 219 client->GetOriginalContext(browser_context_))); | 216 client->GetOriginalContext(browser_context_))); |
| 220 // Close when the browser process is exiting. | 217 // Close when the browser process is exiting. |
| 221 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 218 registrar_.Add(this, |
| 219 chrome::NOTIFICATION_APP_TERMINATING, |
| 222 content::NotificationService::AllSources()); | 220 content::NotificationService::AllSources()); |
| 223 | 221 |
| 224 shell_window_contents_->LoadContents(new_params.creator_process_id); | 222 app_window_contents_->LoadContents(new_params.creator_process_id); |
| 225 | 223 |
| 226 if (CommandLine::ForCurrentProcess()->HasSwitch( | 224 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 227 switches::kEnableAppsShowOnFirstPaint)) { | 225 switches::kEnableAppsShowOnFirstPaint)) { |
| 228 // We want to show the window only when the content has been painted. For | 226 // We want to show the window only when the content has been painted. For |
| 229 // that to happen, we need to define a size for the content, otherwise the | 227 // that to happen, we need to define a size for the content, otherwise the |
| 230 // layout will happen in a 0x0 area. | 228 // layout will happen in a 0x0 area. |
| 231 // Note: WebContents::GetView() is guaranteed to be non-null. | 229 // Note: WebContents::GetView() is guaranteed to be non-null. |
| 232 web_contents->GetView()->SizeContents(new_params.bounds.size()); | 230 web_contents->GetView()->SizeContents(new_params.bounds.size()); |
| 233 } | 231 } |
| 234 | 232 |
| 235 // Prevent the browser process from shutting down while this window is open. | 233 // Prevent the browser process from shutting down while this window is open. |
| 236 chrome::StartKeepAlive(); | 234 chrome::StartKeepAlive(); |
| 237 | 235 |
| 238 UpdateExtensionAppIcon(); | 236 UpdateExtensionAppIcon(); |
| 239 | 237 |
| 240 ShellWindowRegistry::Get(browser_context_)->AddShellWindow(this); | 238 AppWindowRegistry::Get(browser_context_)->AddAppWindow(this); |
| 241 } | 239 } |
| 242 | 240 |
| 243 ShellWindow::~ShellWindow() { | 241 AppWindow::~AppWindow() { |
| 244 // Unregister now to prevent getting NOTIFICATION_APP_TERMINATING if we're the | 242 // Unregister now to prevent getting NOTIFICATION_APP_TERMINATING if we're the |
| 245 // last window open. | 243 // last window open. |
| 246 registrar_.RemoveAll(); | 244 registrar_.RemoveAll(); |
| 247 | 245 |
| 248 // Remove shutdown prevention. | 246 // Remove shutdown prevention. |
| 249 chrome::EndKeepAlive(); | 247 chrome::EndKeepAlive(); |
| 250 } | 248 } |
| 251 | 249 |
| 252 void ShellWindow::RequestMediaAccessPermission( | 250 void AppWindow::RequestMediaAccessPermission( |
| 253 content::WebContents* web_contents, | 251 content::WebContents* web_contents, |
| 254 const content::MediaStreamRequest& request, | 252 const content::MediaStreamRequest& request, |
| 255 const content::MediaResponseCallback& callback) { | 253 const content::MediaResponseCallback& callback) { |
| 256 delegate_->RequestMediaAccessPermission(web_contents, request, callback, | 254 delegate_->RequestMediaAccessPermission( |
| 257 extension()); | 255 web_contents, request, callback, extension()); |
| 258 } | 256 } |
| 259 | 257 |
| 260 WebContents* ShellWindow::OpenURLFromTab(WebContents* source, | 258 WebContents* AppWindow::OpenURLFromTab(WebContents* source, |
| 261 const content::OpenURLParams& params) { | 259 const content::OpenURLParams& params) { |
| 262 // Don't allow the current tab to be navigated. It would be nice to map all | 260 // Don't allow the current tab to be navigated. It would be nice to map all |
| 263 // anchor tags (even those without target="_blank") to new tabs, but right | 261 // anchor tags (even those without target="_blank") to new tabs, but right |
| 264 // now we can't distinguish between those and <meta> refreshes or window.href | 262 // now we can't distinguish between those and <meta> refreshes or window.href |
| 265 // navigations, which we don't want to allow. | 263 // navigations, which we don't want to allow. |
| 266 // TOOD(mihaip): Can we check for user gestures instead? | 264 // TOOD(mihaip): Can we check for user gestures instead? |
| 267 WindowOpenDisposition disposition = params.disposition; | 265 WindowOpenDisposition disposition = params.disposition; |
| 268 if (disposition == CURRENT_TAB) { | 266 if (disposition == CURRENT_TAB) { |
| 269 AddMessageToDevToolsConsole( | 267 AddMessageToDevToolsConsole( |
| 270 content::CONSOLE_MESSAGE_LEVEL_ERROR, | 268 content::CONSOLE_MESSAGE_LEVEL_ERROR, |
| 271 base::StringPrintf( | 269 base::StringPrintf( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 286 AddMessageToDevToolsConsole( | 284 AddMessageToDevToolsConsole( |
| 287 content::CONSOLE_MESSAGE_LEVEL_ERROR, | 285 content::CONSOLE_MESSAGE_LEVEL_ERROR, |
| 288 base::StringPrintf( | 286 base::StringPrintf( |
| 289 "Can't navigate to \"%s\"; apps do not support navigation.", | 287 "Can't navigate to \"%s\"; apps do not support navigation.", |
| 290 params.url.spec().c_str())); | 288 params.url.spec().c_str())); |
| 291 } | 289 } |
| 292 | 290 |
| 293 return contents; | 291 return contents; |
| 294 } | 292 } |
| 295 | 293 |
| 296 void ShellWindow::AddNewContents(WebContents* source, | 294 void AppWindow::AddNewContents(WebContents* source, |
| 297 WebContents* new_contents, | 295 WebContents* new_contents, |
| 298 WindowOpenDisposition disposition, | 296 WindowOpenDisposition disposition, |
| 299 const gfx::Rect& initial_pos, | 297 const gfx::Rect& initial_pos, |
| 300 bool user_gesture, | 298 bool user_gesture, |
| 301 bool* was_blocked) { | 299 bool* was_blocked) { |
| 302 DCHECK(new_contents->GetBrowserContext() == browser_context_); | 300 DCHECK(new_contents->GetBrowserContext() == browser_context_); |
| 303 delegate_->AddNewContents(browser_context_, | 301 delegate_->AddNewContents(browser_context_, |
| 304 new_contents, | 302 new_contents, |
| 305 disposition, | 303 disposition, |
| 306 initial_pos, | 304 initial_pos, |
| 307 user_gesture, | 305 user_gesture, |
| 308 was_blocked); | 306 was_blocked); |
| 309 } | 307 } |
| 310 | 308 |
| 311 bool ShellWindow::PreHandleKeyboardEvent( | 309 bool AppWindow::PreHandleKeyboardEvent( |
| 312 content::WebContents* source, | 310 content::WebContents* source, |
| 313 const content::NativeWebKeyboardEvent& event, | 311 const content::NativeWebKeyboardEvent& event, |
| 314 bool* is_keyboard_shortcut) { | 312 bool* is_keyboard_shortcut) { |
| 315 // Here, we can handle a key event before the content gets it. When we are | 313 // Here, we can handle a key event before the content gets it. When we are |
| 316 // fullscreen and it is not forced, we want to allow the user to leave | 314 // fullscreen and it is not forced, we want to allow the user to leave |
| 317 // when ESC is pressed. | 315 // when ESC is pressed. |
| 318 // However, if the application has the "overrideEscFullscreen" permission, we | 316 // However, if the application has the "overrideEscFullscreen" permission, we |
| 319 // should let it override that behavior. | 317 // should let it override that behavior. |
| 320 // ::HandleKeyboardEvent() will only be called if the KeyEvent's default | 318 // ::HandleKeyboardEvent() will only be called if the KeyEvent's default |
| 321 // action is not prevented. | 319 // action is not prevented. |
| 322 // Thus, we should handle the KeyEvent here only if the permission is not set. | 320 // Thus, we should handle the KeyEvent here only if the permission is not set. |
| 323 if (event.windowsKeyCode == ui::VKEY_ESCAPE && | 321 if (event.windowsKeyCode == ui::VKEY_ESCAPE && |
| 324 (fullscreen_types_ != FULLSCREEN_TYPE_NONE) && | 322 (fullscreen_types_ != FULLSCREEN_TYPE_NONE) && |
| 325 ((fullscreen_types_ & FULLSCREEN_TYPE_FORCED) == 0) && | 323 ((fullscreen_types_ & FULLSCREEN_TYPE_FORCED) == 0) && |
| 326 !extension_->HasAPIPermission(APIPermission::kOverrideEscFullscreen)) { | 324 !extension_->HasAPIPermission(APIPermission::kOverrideEscFullscreen)) { |
| 327 Restore(); | 325 Restore(); |
| 328 return true; | 326 return true; |
| 329 } | 327 } |
| 330 | 328 |
| 331 return false; | 329 return false; |
| 332 } | 330 } |
| 333 | 331 |
| 334 void ShellWindow::HandleKeyboardEvent( | 332 void AppWindow::HandleKeyboardEvent( |
| 335 WebContents* source, | 333 WebContents* source, |
| 336 const content::NativeWebKeyboardEvent& event) { | 334 const content::NativeWebKeyboardEvent& event) { |
| 337 // If the window is currently fullscreen and not forced, ESC should leave | 335 // If the window is currently fullscreen and not forced, ESC should leave |
| 338 // fullscreen. If this code is being called for ESC, that means that the | 336 // fullscreen. If this code is being called for ESC, that means that the |
| 339 // KeyEvent's default behavior was not prevented by the content. | 337 // KeyEvent's default behavior was not prevented by the content. |
| 340 if (event.windowsKeyCode == ui::VKEY_ESCAPE && | 338 if (event.windowsKeyCode == ui::VKEY_ESCAPE && |
| 341 (fullscreen_types_ != FULLSCREEN_TYPE_NONE) && | 339 (fullscreen_types_ != FULLSCREEN_TYPE_NONE) && |
| 342 ((fullscreen_types_ & FULLSCREEN_TYPE_FORCED) == 0)) { | 340 ((fullscreen_types_ & FULLSCREEN_TYPE_FORCED) == 0)) { |
| 343 Restore(); | 341 Restore(); |
| 344 return; | 342 return; |
| 345 } | 343 } |
| 346 | 344 |
| 347 native_app_window_->HandleKeyboardEvent(event); | 345 native_app_window_->HandleKeyboardEvent(event); |
| 348 } | 346 } |
| 349 | 347 |
| 350 void ShellWindow::RequestToLockMouse(WebContents* web_contents, | 348 void AppWindow::RequestToLockMouse(WebContents* web_contents, |
| 351 bool user_gesture, | 349 bool user_gesture, |
| 352 bool last_unlocked_by_target) { | 350 bool last_unlocked_by_target) { |
| 353 bool has_permission = IsExtensionWithPermissionOrSuggestInConsole( | 351 bool has_permission = IsExtensionWithPermissionOrSuggestInConsole( |
| 354 APIPermission::kPointerLock, | 352 APIPermission::kPointerLock, |
| 355 extension_, | 353 extension_, |
| 356 web_contents->GetRenderViewHost()); | 354 web_contents->GetRenderViewHost()); |
| 357 | 355 |
| 358 web_contents->GotResponseToLockMouseRequest(has_permission); | 356 web_contents->GotResponseToLockMouseRequest(has_permission); |
| 359 } | 357 } |
| 360 | 358 |
| 361 bool ShellWindow::PreHandleGestureEvent( | 359 bool AppWindow::PreHandleGestureEvent(WebContents* source, |
| 362 WebContents* source, | 360 const blink::WebGestureEvent& event) { |
| 363 const blink::WebGestureEvent& event) { | 361 // Disable pinch zooming in app windows. |
| 364 // Disable pinch zooming in shell windows. | |
| 365 return event.type == blink::WebGestureEvent::GesturePinchBegin || | 362 return event.type == blink::WebGestureEvent::GesturePinchBegin || |
| 366 event.type == blink::WebGestureEvent::GesturePinchUpdate || | 363 event.type == blink::WebGestureEvent::GesturePinchUpdate || |
| 367 event.type == blink::WebGestureEvent::GesturePinchEnd; | 364 event.type == blink::WebGestureEvent::GesturePinchEnd; |
| 368 } | 365 } |
| 369 | 366 |
| 370 void ShellWindow::DidFirstVisuallyNonEmptyPaint(int32 page_id) { | 367 void AppWindow::DidFirstVisuallyNonEmptyPaint(int32 page_id) { |
| 371 first_paint_complete_ = true; | 368 first_paint_complete_ = true; |
| 372 if (show_on_first_paint_) { | 369 if (show_on_first_paint_) { |
| 373 DCHECK(delayed_show_type_ == SHOW_ACTIVE || | 370 DCHECK(delayed_show_type_ == SHOW_ACTIVE || |
| 374 delayed_show_type_ == SHOW_INACTIVE); | 371 delayed_show_type_ == SHOW_INACTIVE); |
| 375 Show(delayed_show_type_); | 372 Show(delayed_show_type_); |
| 376 } | 373 } |
| 377 } | 374 } |
| 378 | 375 |
| 379 void ShellWindow::OnNativeClose() { | 376 void AppWindow::OnNativeClose() { |
| 380 ShellWindowRegistry::Get(browser_context_)->RemoveShellWindow(this); | 377 AppWindowRegistry::Get(browser_context_)->RemoveAppWindow(this); |
| 381 if (shell_window_contents_) { | 378 if (app_window_contents_) { |
| 382 WebContents* web_contents = shell_window_contents_->GetWebContents(); | 379 WebContents* web_contents = app_window_contents_->GetWebContents(); |
| 383 WebContentsModalDialogManager::FromWebContents(web_contents)-> | 380 WebContentsModalDialogManager::FromWebContents(web_contents) |
| 384 SetDelegate(NULL); | 381 ->SetDelegate(NULL); |
| 385 shell_window_contents_->NativeWindowClosed(); | 382 app_window_contents_->NativeWindowClosed(); |
| 386 } | 383 } |
| 387 delete this; | 384 delete this; |
| 388 } | 385 } |
| 389 | 386 |
| 390 void ShellWindow::OnNativeWindowChanged() { | 387 void AppWindow::OnNativeWindowChanged() { |
| 391 SaveWindowPosition(); | 388 SaveWindowPosition(); |
| 392 | 389 |
| 393 #if defined(OS_WIN) | 390 #if defined(OS_WIN) |
| 394 if (native_app_window_ && | 391 if (native_app_window_ && cached_always_on_top_ && |
| 395 cached_always_on_top_ && | 392 !IsFullscreen(fullscreen_types_) && !native_app_window_->IsMaximized() && |
| 396 !IsFullscreen(fullscreen_types_) && | |
| 397 !native_app_window_->IsMaximized() && | |
| 398 !native_app_window_->IsMinimized()) { | 393 !native_app_window_->IsMinimized()) { |
| 399 UpdateNativeAlwaysOnTop(); | 394 UpdateNativeAlwaysOnTop(); |
| 400 } | 395 } |
| 401 #endif | 396 #endif |
| 402 | 397 |
| 403 if (shell_window_contents_ && native_app_window_) | 398 if (app_window_contents_ && native_app_window_) |
| 404 shell_window_contents_->NativeWindowChanged(native_app_window_.get()); | 399 app_window_contents_->NativeWindowChanged(native_app_window_.get()); |
| 405 } | 400 } |
| 406 | 401 |
| 407 void ShellWindow::OnNativeWindowActivated() { | 402 void AppWindow::OnNativeWindowActivated() { |
| 408 ShellWindowRegistry::Get(browser_context_)->ShellWindowActivated(this); | 403 AppWindowRegistry::Get(browser_context_)->AppWindowActivated(this); |
| 409 } | 404 } |
| 410 | 405 |
| 411 content::WebContents* ShellWindow::web_contents() const { | 406 content::WebContents* AppWindow::web_contents() const { |
| 412 return shell_window_contents_->GetWebContents(); | 407 return app_window_contents_->GetWebContents(); |
| 413 } | 408 } |
| 414 | 409 |
| 415 NativeAppWindow* ShellWindow::GetBaseWindow() { | 410 NativeAppWindow* AppWindow::GetBaseWindow() { return native_app_window_.get(); } |
| 416 return native_app_window_.get(); | |
| 417 } | |
| 418 | 411 |
| 419 gfx::NativeWindow ShellWindow::GetNativeWindow() { | 412 gfx::NativeWindow AppWindow::GetNativeWindow() { |
| 420 return GetBaseWindow()->GetNativeWindow(); | 413 return GetBaseWindow()->GetNativeWindow(); |
| 421 } | 414 } |
| 422 | 415 |
| 423 gfx::Rect ShellWindow::GetClientBounds() const { | 416 gfx::Rect AppWindow::GetClientBounds() const { |
| 424 gfx::Rect bounds = native_app_window_->GetBounds(); | 417 gfx::Rect bounds = native_app_window_->GetBounds(); |
| 425 bounds.Inset(native_app_window_->GetFrameInsets()); | 418 bounds.Inset(native_app_window_->GetFrameInsets()); |
| 426 return bounds; | 419 return bounds; |
| 427 } | 420 } |
| 428 | 421 |
| 429 base::string16 ShellWindow::GetTitle() const { | 422 base::string16 AppWindow::GetTitle() const { |
| 430 // WebContents::GetTitle() will return the page's URL if there's no <title> | 423 // WebContents::GetTitle() will return the page's URL if there's no <title> |
| 431 // specified. However, we'd prefer to show the name of the extension in that | 424 // specified. However, we'd prefer to show the name of the extension in that |
| 432 // case, so we directly inspect the NavigationEntry's title. | 425 // case, so we directly inspect the NavigationEntry's title. |
| 433 base::string16 title; | 426 base::string16 title; |
| 434 if (!web_contents() || | 427 if (!web_contents() || !web_contents()->GetController().GetActiveEntry() || |
| 435 !web_contents()->GetController().GetActiveEntry() || | |
| 436 web_contents()->GetController().GetActiveEntry()->GetTitle().empty()) { | 428 web_contents()->GetController().GetActiveEntry()->GetTitle().empty()) { |
| 437 title = base::UTF8ToUTF16(extension()->name()); | 429 title = base::UTF8ToUTF16(extension()->name()); |
| 438 } else { | 430 } else { |
| 439 title = web_contents()->GetTitle(); | 431 title = web_contents()->GetTitle(); |
| 440 } | 432 } |
| 441 const base::char16 kBadChars[] = { '\n', 0 }; | 433 const base::char16 kBadChars[] = {'\n', 0}; |
| 442 base::RemoveChars(title, kBadChars, &title); | 434 base::RemoveChars(title, kBadChars, &title); |
| 443 return title; | 435 return title; |
| 444 } | 436 } |
| 445 | 437 |
| 446 void ShellWindow::SetAppIconUrl(const GURL& url) { | 438 void AppWindow::SetAppIconUrl(const GURL& url) { |
| 447 // If the same url is being used for the badge, ignore it. | 439 // If the same url is being used for the badge, ignore it. |
| 448 if (url == badge_icon_url_) | 440 if (url == badge_icon_url_) |
| 449 return; | 441 return; |
| 450 | 442 |
| 451 // Avoid using any previous icons that were being downloaded. | 443 // Avoid using any previous icons that were being downloaded. |
| 452 image_loader_ptr_factory_.InvalidateWeakPtrs(); | 444 image_loader_ptr_factory_.InvalidateWeakPtrs(); |
| 453 | 445 |
| 454 // Reset |app_icon_image_| to abort pending image load (if any). | 446 // Reset |app_icon_image_| to abort pending image load (if any). |
| 455 app_icon_image_.reset(); | 447 app_icon_image_.reset(); |
| 456 | 448 |
| 457 app_icon_url_ = url; | 449 app_icon_url_ = url; |
| 458 web_contents()->DownloadImage( | 450 web_contents()->DownloadImage( |
| 459 url, | 451 url, |
| 460 true, // is a favicon | 452 true, // is a favicon |
| 461 0, // no maximum size | 453 0, // no maximum size |
| 462 base::Bind(&ShellWindow::DidDownloadFavicon, | 454 base::Bind(&AppWindow::DidDownloadFavicon, |
| 463 image_loader_ptr_factory_.GetWeakPtr())); | 455 image_loader_ptr_factory_.GetWeakPtr())); |
| 464 } | 456 } |
| 465 | 457 |
| 466 void ShellWindow::SetBadgeIconUrl(const GURL& url) { | 458 void AppWindow::SetBadgeIconUrl(const GURL& url) { |
| 467 // Avoid using any previous icons that were being downloaded. | 459 // Avoid using any previous icons that were being downloaded. |
| 468 image_loader_ptr_factory_.InvalidateWeakPtrs(); | 460 image_loader_ptr_factory_.InvalidateWeakPtrs(); |
| 469 | 461 |
| 470 // Reset |app_icon_image_| to abort pending image load (if any). | 462 // Reset |app_icon_image_| to abort pending image load (if any). |
| 471 badge_icon_image_.reset(); | 463 badge_icon_image_.reset(); |
| 472 | 464 |
| 473 badge_icon_url_ = url; | 465 badge_icon_url_ = url; |
| 474 web_contents()->DownloadImage( | 466 web_contents()->DownloadImage( |
| 475 url, | 467 url, |
| 476 true, // is a favicon | 468 true, // is a favicon |
| 477 0, // no maximum size | 469 0, // no maximum size |
| 478 base::Bind(&ShellWindow::DidDownloadFavicon, | 470 base::Bind(&AppWindow::DidDownloadFavicon, |
| 479 image_loader_ptr_factory_.GetWeakPtr())); | 471 image_loader_ptr_factory_.GetWeakPtr())); |
| 480 } | 472 } |
| 481 | 473 |
| 482 void ShellWindow::ClearBadge() { | 474 void AppWindow::ClearBadge() { |
| 483 badge_icon_image_.reset(); | 475 badge_icon_image_.reset(); |
| 484 badge_icon_url_ = GURL(); | 476 badge_icon_url_ = GURL(); |
| 485 UpdateBadgeIcon(gfx::Image()); | 477 UpdateBadgeIcon(gfx::Image()); |
| 486 } | 478 } |
| 487 | 479 |
| 488 void ShellWindow::UpdateShape(scoped_ptr<SkRegion> region) { | 480 void AppWindow::UpdateShape(scoped_ptr<SkRegion> region) { |
| 489 native_app_window_->UpdateShape(region.Pass()); | 481 native_app_window_->UpdateShape(region.Pass()); |
| 490 } | 482 } |
| 491 | 483 |
| 492 void ShellWindow::UpdateDraggableRegions( | 484 void AppWindow::UpdateDraggableRegions( |
| 493 const std::vector<extensions::DraggableRegion>& regions) { | 485 const std::vector<extensions::DraggableRegion>& regions) { |
| 494 native_app_window_->UpdateDraggableRegions(regions); | 486 native_app_window_->UpdateDraggableRegions(regions); |
| 495 } | 487 } |
| 496 | 488 |
| 497 void ShellWindow::UpdateAppIcon(const gfx::Image& image) { | 489 void AppWindow::UpdateAppIcon(const gfx::Image& image) { |
| 498 if (image.IsEmpty()) | 490 if (image.IsEmpty()) |
| 499 return; | 491 return; |
| 500 app_icon_ = image; | 492 app_icon_ = image; |
| 501 native_app_window_->UpdateWindowIcon(); | 493 native_app_window_->UpdateWindowIcon(); |
| 502 ShellWindowRegistry::Get(browser_context_)->ShellWindowIconChanged(this); | 494 AppWindowRegistry::Get(browser_context_)->AppWindowIconChanged(this); |
| 503 } | 495 } |
| 504 | 496 |
| 505 void ShellWindow::Fullscreen() { | 497 void AppWindow::Fullscreen() { |
| 506 #if !defined(OS_MACOSX) | 498 #if !defined(OS_MACOSX) |
| 507 // Do not enter fullscreen mode if disallowed by pref. | 499 // Do not enter fullscreen mode if disallowed by pref. |
| 508 PrefService* prefs = | 500 PrefService* prefs = |
| 509 extensions::ExtensionsBrowserClient::Get()->GetPrefServiceForContext( | 501 extensions::ExtensionsBrowserClient::Get()->GetPrefServiceForContext( |
| 510 browser_context()); | 502 browser_context()); |
| 511 if (!prefs->GetBoolean(prefs::kAppFullscreenAllowed)) | 503 if (!prefs->GetBoolean(prefs::kAppFullscreenAllowed)) |
| 512 return; | 504 return; |
| 513 #endif | 505 #endif |
| 514 fullscreen_types_ |= FULLSCREEN_TYPE_WINDOW_API; | 506 fullscreen_types_ |= FULLSCREEN_TYPE_WINDOW_API; |
| 515 SetNativeWindowFullscreen(); | 507 SetNativeWindowFullscreen(); |
| 516 } | 508 } |
| 517 | 509 |
| 518 void ShellWindow::Maximize() { | 510 void AppWindow::Maximize() { GetBaseWindow()->Maximize(); } |
| 519 GetBaseWindow()->Maximize(); | |
| 520 } | |
| 521 | 511 |
| 522 void ShellWindow::Minimize() { | 512 void AppWindow::Minimize() { GetBaseWindow()->Minimize(); } |
| 523 GetBaseWindow()->Minimize(); | |
| 524 } | |
| 525 | 513 |
| 526 void ShellWindow::Restore() { | 514 void AppWindow::Restore() { |
| 527 if (IsFullscreen(fullscreen_types_)) { | 515 if (IsFullscreen(fullscreen_types_)) { |
| 528 fullscreen_types_ = FULLSCREEN_TYPE_NONE; | 516 fullscreen_types_ = FULLSCREEN_TYPE_NONE; |
| 529 SetNativeWindowFullscreen(); | 517 SetNativeWindowFullscreen(); |
| 530 } else { | 518 } else { |
| 531 GetBaseWindow()->Restore(); | 519 GetBaseWindow()->Restore(); |
| 532 } | 520 } |
| 533 } | 521 } |
| 534 | 522 |
| 535 void ShellWindow::OSFullscreen() { | 523 void AppWindow::OSFullscreen() { |
| 536 #if !defined(OS_MACOSX) | 524 #if !defined(OS_MACOSX) |
| 537 // Do not enter fullscreen mode if disallowed by pref. | 525 // Do not enter fullscreen mode if disallowed by pref. |
| 538 PrefService* prefs = | 526 PrefService* prefs = |
| 539 extensions::ExtensionsBrowserClient::Get()->GetPrefServiceForContext( | 527 extensions::ExtensionsBrowserClient::Get()->GetPrefServiceForContext( |
| 540 browser_context()); | 528 browser_context()); |
| 541 if (!prefs->GetBoolean(prefs::kAppFullscreenAllowed)) | 529 if (!prefs->GetBoolean(prefs::kAppFullscreenAllowed)) |
| 542 return; | 530 return; |
| 543 #endif | 531 #endif |
| 544 fullscreen_types_ |= FULLSCREEN_TYPE_OS; | 532 fullscreen_types_ |= FULLSCREEN_TYPE_OS; |
| 545 SetNativeWindowFullscreen(); | 533 SetNativeWindowFullscreen(); |
| 546 } | 534 } |
| 547 | 535 |
| 548 void ShellWindow::ForcedFullscreen() { | 536 void AppWindow::ForcedFullscreen() { |
| 549 fullscreen_types_ |= FULLSCREEN_TYPE_FORCED; | 537 fullscreen_types_ |= FULLSCREEN_TYPE_FORCED; |
| 550 SetNativeWindowFullscreen(); | 538 SetNativeWindowFullscreen(); |
| 551 } | 539 } |
| 552 | 540 |
| 553 void ShellWindow::SetMinimumSize(const gfx::Size& min_size) { | 541 void AppWindow::SetMinimumSize(const gfx::Size& min_size) { |
| 554 size_constraints_.set_minimum_size(min_size); | 542 size_constraints_.set_minimum_size(min_size); |
| 555 OnSizeConstraintsChanged(); | 543 OnSizeConstraintsChanged(); |
| 556 } | 544 } |
| 557 | 545 |
| 558 void ShellWindow::SetMaximumSize(const gfx::Size& max_size) { | 546 void AppWindow::SetMaximumSize(const gfx::Size& max_size) { |
| 559 size_constraints_.set_maximum_size(max_size); | 547 size_constraints_.set_maximum_size(max_size); |
| 560 OnSizeConstraintsChanged(); | 548 OnSizeConstraintsChanged(); |
| 561 } | 549 } |
| 562 | 550 |
| 563 void ShellWindow::Show(ShowType show_type) { | 551 void AppWindow::Show(ShowType show_type) { |
| 564 if (CommandLine::ForCurrentProcess()->HasSwitch( | 552 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 565 switches::kEnableAppsShowOnFirstPaint)) { | 553 switches::kEnableAppsShowOnFirstPaint)) { |
| 566 show_on_first_paint_ = true; | 554 show_on_first_paint_ = true; |
| 567 | 555 |
| 568 if (!first_paint_complete_) { | 556 if (!first_paint_complete_) { |
| 569 delayed_show_type_ = show_type; | 557 delayed_show_type_ = show_type; |
| 570 return; | 558 return; |
| 571 } | 559 } |
| 572 } | 560 } |
| 573 | 561 |
| 574 switch (show_type) { | 562 switch (show_type) { |
| 575 case SHOW_ACTIVE: | 563 case SHOW_ACTIVE: |
| 576 GetBaseWindow()->Show(); | 564 GetBaseWindow()->Show(); |
| 577 break; | 565 break; |
| 578 case SHOW_INACTIVE: | 566 case SHOW_INACTIVE: |
| 579 GetBaseWindow()->ShowInactive(); | 567 GetBaseWindow()->ShowInactive(); |
| 580 break; | 568 break; |
| 581 } | 569 } |
| 582 } | 570 } |
| 583 | 571 |
| 584 void ShellWindow::Hide() { | 572 void AppWindow::Hide() { |
| 585 // This is there to prevent race conditions with Hide() being called before | 573 // This is there to prevent race conditions with Hide() being called before |
| 586 // there was a non-empty paint. It should have no effect in a non-racy | 574 // there was a non-empty paint. It should have no effect in a non-racy |
| 587 // scenario where the application is hiding then showing a window: the second | 575 // scenario where the application is hiding then showing a window: the second |
| 588 // show will not be delayed. | 576 // show will not be delayed. |
| 589 show_on_first_paint_ = false; | 577 show_on_first_paint_ = false; |
| 590 GetBaseWindow()->Hide(); | 578 GetBaseWindow()->Hide(); |
| 591 } | 579 } |
| 592 | 580 |
| 593 void ShellWindow::SetAlwaysOnTop(bool always_on_top) { | 581 void AppWindow::SetAlwaysOnTop(bool always_on_top) { |
| 594 if (cached_always_on_top_ == always_on_top) | 582 if (cached_always_on_top_ == always_on_top) |
| 595 return; | 583 return; |
| 596 | 584 |
| 597 cached_always_on_top_ = always_on_top; | 585 cached_always_on_top_ = always_on_top; |
| 598 | 586 |
| 599 // As a security measure, do not allow fullscreen windows or windows that | 587 // As a security measure, do not allow fullscreen windows or windows that |
| 600 // overlap the taskbar to be on top. The property will be applied when the | 588 // overlap the taskbar to be on top. The property will be applied when the |
| 601 // window exits fullscreen and moves away from the taskbar. | 589 // window exits fullscreen and moves away from the taskbar. |
| 602 if (!IsFullscreen(fullscreen_types_) && !IntersectsWithTaskbar()) | 590 if (!IsFullscreen(fullscreen_types_) && !IntersectsWithTaskbar()) |
| 603 native_app_window_->SetAlwaysOnTop(always_on_top); | 591 native_app_window_->SetAlwaysOnTop(always_on_top); |
| 604 | 592 |
| 605 OnNativeWindowChanged(); | 593 OnNativeWindowChanged(); |
| 606 } | 594 } |
| 607 | 595 |
| 608 bool ShellWindow::IsAlwaysOnTop() const { | 596 bool AppWindow::IsAlwaysOnTop() const { return cached_always_on_top_; } |
| 609 return cached_always_on_top_; | |
| 610 } | |
| 611 | 597 |
| 612 void ShellWindow::GetSerializedState(base::DictionaryValue* properties) const { | 598 void AppWindow::GetSerializedState(base::DictionaryValue* properties) const { |
| 613 DCHECK(properties); | 599 DCHECK(properties); |
| 614 | 600 |
| 615 properties->SetBoolean("fullscreen", | 601 properties->SetBoolean("fullscreen", |
| 616 native_app_window_->IsFullscreenOrPending()); | 602 native_app_window_->IsFullscreenOrPending()); |
| 617 properties->SetBoolean("minimized", native_app_window_->IsMinimized()); | 603 properties->SetBoolean("minimized", native_app_window_->IsMinimized()); |
| 618 properties->SetBoolean("maximized", native_app_window_->IsMaximized()); | 604 properties->SetBoolean("maximized", native_app_window_->IsMaximized()); |
| 619 properties->SetBoolean("alwaysOnTop", IsAlwaysOnTop()); | 605 properties->SetBoolean("alwaysOnTop", IsAlwaysOnTop()); |
| 620 scoped_ptr<base::DictionaryValue> boundsValue(new base::DictionaryValue()); | 606 scoped_ptr<base::DictionaryValue> boundsValue(new base::DictionaryValue()); |
| 621 gfx::Rect bounds = GetClientBounds(); | 607 gfx::Rect bounds = GetClientBounds(); |
| 622 boundsValue->SetInteger("left", bounds.x()); | 608 boundsValue->SetInteger("left", bounds.x()); |
| 623 boundsValue->SetInteger("top", bounds.y()); | 609 boundsValue->SetInteger("top", bounds.y()); |
| 624 boundsValue->SetInteger("width", bounds.width()); | 610 boundsValue->SetInteger("width", bounds.width()); |
| 625 boundsValue->SetInteger("height", bounds.height()); | 611 boundsValue->SetInteger("height", bounds.height()); |
| 626 properties->Set("bounds", boundsValue.release()); | 612 properties->Set("bounds", boundsValue.release()); |
| 627 | 613 |
| 628 const SizeConstraints& constraints = size_constraints(); | 614 const SizeConstraints& constraints = size_constraints(); |
| 629 gfx::Size min_size = constraints.GetMinimumSize(); | 615 gfx::Size min_size = constraints.GetMinimumSize(); |
| 630 gfx::Size max_size = constraints.GetMaximumSize(); | 616 gfx::Size max_size = constraints.GetMaximumSize(); |
| 631 if (min_size.width() != SizeConstraints::kUnboundedSize) | 617 if (min_size.width() != SizeConstraints::kUnboundedSize) |
| 632 properties->SetInteger("minWidth", min_size.width()); | 618 properties->SetInteger("minWidth", min_size.width()); |
| 633 if (min_size.height() != SizeConstraints::kUnboundedSize) | 619 if (min_size.height() != SizeConstraints::kUnboundedSize) |
| 634 properties->SetInteger("minHeight", min_size.height()); | 620 properties->SetInteger("minHeight", min_size.height()); |
| 635 if (max_size.width() != SizeConstraints::kUnboundedSize) | 621 if (max_size.width() != SizeConstraints::kUnboundedSize) |
| 636 properties->SetInteger("maxWidth", max_size.width()); | 622 properties->SetInteger("maxWidth", max_size.width()); |
| 637 if (max_size.height() != SizeConstraints::kUnboundedSize) | 623 if (max_size.height() != SizeConstraints::kUnboundedSize) |
| 638 properties->SetInteger("maxHeight", max_size.height()); | 624 properties->SetInteger("maxHeight", max_size.height()); |
| 639 } | 625 } |
| 640 | 626 |
| 641 //------------------------------------------------------------------------------ | 627 //------------------------------------------------------------------------------ |
| 642 // Private methods | 628 // Private methods |
| 643 | 629 |
| 644 void ShellWindow::UpdateBadgeIcon(const gfx::Image& image) { | 630 void AppWindow::UpdateBadgeIcon(const gfx::Image& image) { |
| 645 badge_icon_ = image; | 631 badge_icon_ = image; |
| 646 native_app_window_->UpdateBadgeIcon(); | 632 native_app_window_->UpdateBadgeIcon(); |
| 647 } | 633 } |
| 648 | 634 |
| 649 void ShellWindow::DidDownloadFavicon( | 635 void AppWindow::DidDownloadFavicon( |
| 650 int id, | 636 int id, |
| 651 int http_status_code, | 637 int http_status_code, |
| 652 const GURL& image_url, | 638 const GURL& image_url, |
| 653 const std::vector<SkBitmap>& bitmaps, | 639 const std::vector<SkBitmap>& bitmaps, |
| 654 const std::vector<gfx::Size>& original_bitmap_sizes) { | 640 const std::vector<gfx::Size>& original_bitmap_sizes) { |
| 655 if ((image_url != app_icon_url_ && image_url != badge_icon_url_) || | 641 if ((image_url != app_icon_url_ && image_url != badge_icon_url_) || |
| 656 bitmaps.empty()) { | 642 bitmaps.empty()) { |
| 657 return; | 643 return; |
| 658 } | 644 } |
| 659 | 645 |
| 660 // Bitmaps are ordered largest to smallest. Choose the smallest bitmap | 646 // Bitmaps are ordered largest to smallest. Choose the smallest bitmap |
| 661 // whose height >= the preferred size. | 647 // whose height >= the preferred size. |
| 662 int largest_index = 0; | 648 int largest_index = 0; |
| 663 for (size_t i = 1; i < bitmaps.size(); ++i) { | 649 for (size_t i = 1; i < bitmaps.size(); ++i) { |
| 664 if (bitmaps[i].height() < delegate_->PreferredIconSize()) | 650 if (bitmaps[i].height() < delegate_->PreferredIconSize()) |
| 665 break; | 651 break; |
| 666 largest_index = i; | 652 largest_index = i; |
| 667 } | 653 } |
| 668 const SkBitmap& largest = bitmaps[largest_index]; | 654 const SkBitmap& largest = bitmaps[largest_index]; |
| 669 if (image_url == app_icon_url_) { | 655 if (image_url == app_icon_url_) { |
| 670 UpdateAppIcon(gfx::Image::CreateFrom1xBitmap(largest)); | 656 UpdateAppIcon(gfx::Image::CreateFrom1xBitmap(largest)); |
| 671 return; | 657 return; |
| 672 } | 658 } |
| 673 | 659 |
| 674 UpdateBadgeIcon(gfx::Image::CreateFrom1xBitmap(largest)); | 660 UpdateBadgeIcon(gfx::Image::CreateFrom1xBitmap(largest)); |
| 675 } | 661 } |
| 676 | 662 |
| 677 void ShellWindow::OnExtensionIconImageChanged(extensions::IconImage* image) { | 663 void AppWindow::OnExtensionIconImageChanged(extensions::IconImage* image) { |
| 678 DCHECK_EQ(app_icon_image_.get(), image); | 664 DCHECK_EQ(app_icon_image_.get(), image); |
| 679 | 665 |
| 680 UpdateAppIcon(gfx::Image(app_icon_image_->image_skia())); | 666 UpdateAppIcon(gfx::Image(app_icon_image_->image_skia())); |
| 681 } | 667 } |
| 682 | 668 |
| 683 void ShellWindow::UpdateExtensionAppIcon() { | 669 void AppWindow::UpdateExtensionAppIcon() { |
| 684 // Avoid using any previous app icons were being downloaded. | 670 // Avoid using any previous app icons were being downloaded. |
| 685 image_loader_ptr_factory_.InvalidateWeakPtrs(); | 671 image_loader_ptr_factory_.InvalidateWeakPtrs(); |
| 686 | 672 |
| 687 app_icon_image_.reset( | 673 app_icon_image_.reset( |
| 688 new extensions::IconImage(browser_context(), | 674 new extensions::IconImage(browser_context(), |
| 689 extension(), | 675 extension(), |
| 690 extensions::IconsInfo::GetIcons(extension()), | 676 extensions::IconsInfo::GetIcons(extension()), |
| 691 delegate_->PreferredIconSize(), | 677 delegate_->PreferredIconSize(), |
| 692 extensions::IconsInfo::GetDefaultAppIcon(), | 678 extensions::IconsInfo::GetDefaultAppIcon(), |
| 693 this)); | 679 this)); |
| 694 | 680 |
| 695 // Triggers actual image loading with 1x resources. The 2x resource will | 681 // Triggers actual image loading with 1x resources. The 2x resource will |
| 696 // be handled by IconImage class when requested. | 682 // be handled by IconImage class when requested. |
| 697 app_icon_image_->image_skia().GetRepresentation(1.0f); | 683 app_icon_image_->image_skia().GetRepresentation(1.0f); |
| 698 } | 684 } |
| 699 | 685 |
| 700 void ShellWindow::OnSizeConstraintsChanged() { | 686 void AppWindow::OnSizeConstraintsChanged() { |
| 701 native_app_window_->UpdateWindowMinMaxSize(); | 687 native_app_window_->UpdateWindowMinMaxSize(); |
| 702 gfx::Rect bounds = GetClientBounds(); | 688 gfx::Rect bounds = GetClientBounds(); |
| 703 gfx::Size constrained_size = size_constraints_.ClampSize(bounds.size()); | 689 gfx::Size constrained_size = size_constraints_.ClampSize(bounds.size()); |
| 704 if (bounds.size() != constrained_size) { | 690 if (bounds.size() != constrained_size) { |
| 705 bounds.set_size(constrained_size); | 691 bounds.set_size(constrained_size); |
| 706 native_app_window_->SetBounds(bounds); | 692 native_app_window_->SetBounds(bounds); |
| 707 } | 693 } |
| 708 OnNativeWindowChanged(); | 694 OnNativeWindowChanged(); |
| 709 } | 695 } |
| 710 | 696 |
| 711 void ShellWindow::SetNativeWindowFullscreen() { | 697 void AppWindow::SetNativeWindowFullscreen() { |
| 712 native_app_window_->SetFullscreen(fullscreen_types_); | 698 native_app_window_->SetFullscreen(fullscreen_types_); |
| 713 | 699 |
| 714 if (cached_always_on_top_) | 700 if (cached_always_on_top_) |
| 715 UpdateNativeAlwaysOnTop(); | 701 UpdateNativeAlwaysOnTop(); |
| 716 } | 702 } |
| 717 | 703 |
| 718 bool ShellWindow::IntersectsWithTaskbar() const { | 704 bool AppWindow::IntersectsWithTaskbar() const { |
| 719 #if defined(OS_WIN) | 705 #if defined(OS_WIN) |
| 720 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | 706 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); |
| 721 gfx::Rect window_bounds = native_app_window_->GetRestoredBounds(); | 707 gfx::Rect window_bounds = native_app_window_->GetRestoredBounds(); |
| 722 std::vector<gfx::Display> displays = screen->GetAllDisplays(); | 708 std::vector<gfx::Display> displays = screen->GetAllDisplays(); |
| 723 | 709 |
| 724 for (std::vector<gfx::Display>::const_iterator it = displays.begin(); | 710 for (std::vector<gfx::Display>::const_iterator it = displays.begin(); |
| 725 it != displays.end(); ++it) { | 711 it != displays.end(); |
| 712 ++it) { |
| 726 gfx::Rect taskbar_bounds = it->bounds(); | 713 gfx::Rect taskbar_bounds = it->bounds(); |
| 727 taskbar_bounds.Subtract(it->work_area()); | 714 taskbar_bounds.Subtract(it->work_area()); |
| 728 if (taskbar_bounds.IsEmpty()) | 715 if (taskbar_bounds.IsEmpty()) |
| 729 continue; | 716 continue; |
| 730 | 717 |
| 731 if (window_bounds.Intersects(taskbar_bounds)) | 718 if (window_bounds.Intersects(taskbar_bounds)) |
| 732 return true; | 719 return true; |
| 733 } | 720 } |
| 734 #endif | 721 #endif |
| 735 | 722 |
| 736 return false; | 723 return false; |
| 737 } | 724 } |
| 738 | 725 |
| 739 void ShellWindow::UpdateNativeAlwaysOnTop() { | 726 void AppWindow::UpdateNativeAlwaysOnTop() { |
| 740 DCHECK(cached_always_on_top_); | 727 DCHECK(cached_always_on_top_); |
| 741 bool is_on_top = native_app_window_->IsAlwaysOnTop(); | 728 bool is_on_top = native_app_window_->IsAlwaysOnTop(); |
| 742 bool fullscreen = IsFullscreen(fullscreen_types_); | 729 bool fullscreen = IsFullscreen(fullscreen_types_); |
| 743 bool intersects_taskbar = IntersectsWithTaskbar(); | 730 bool intersects_taskbar = IntersectsWithTaskbar(); |
| 744 | 731 |
| 745 if (is_on_top && (fullscreen || intersects_taskbar)) { | 732 if (is_on_top && (fullscreen || intersects_taskbar)) { |
| 746 // When entering fullscreen or overlapping the taskbar, ensure windows are | 733 // When entering fullscreen or overlapping the taskbar, ensure windows are |
| 747 // not always-on-top. | 734 // not always-on-top. |
| 748 native_app_window_->SetAlwaysOnTop(false); | 735 native_app_window_->SetAlwaysOnTop(false); |
| 749 } else if (!is_on_top && !fullscreen && !intersects_taskbar) { | 736 } else if (!is_on_top && !fullscreen && !intersects_taskbar) { |
| 750 // When exiting fullscreen and moving away from the taskbar, reinstate | 737 // When exiting fullscreen and moving away from the taskbar, reinstate |
| 751 // always-on-top. | 738 // always-on-top. |
| 752 native_app_window_->SetAlwaysOnTop(true); | 739 native_app_window_->SetAlwaysOnTop(true); |
| 753 } | 740 } |
| 754 } | 741 } |
| 755 | 742 |
| 756 void ShellWindow::CloseContents(WebContents* contents) { | 743 void AppWindow::CloseContents(WebContents* contents) { |
| 757 native_app_window_->Close(); | 744 native_app_window_->Close(); |
| 758 } | 745 } |
| 759 | 746 |
| 760 bool ShellWindow::ShouldSuppressDialogs() { | 747 bool AppWindow::ShouldSuppressDialogs() { return true; } |
| 761 return true; | |
| 762 } | |
| 763 | 748 |
| 764 content::ColorChooser* ShellWindow::OpenColorChooser( | 749 content::ColorChooser* AppWindow::OpenColorChooser( |
| 765 WebContents* web_contents, | 750 WebContents* web_contents, |
| 766 SkColor initial_color, | 751 SkColor initial_color, |
| 767 const std::vector<content::ColorSuggestion>& suggestionss) { | 752 const std::vector<content::ColorSuggestion>& suggestionss) { |
| 768 return delegate_->ShowColorChooser(web_contents, initial_color); | 753 return delegate_->ShowColorChooser(web_contents, initial_color); |
| 769 } | 754 } |
| 770 | 755 |
| 771 void ShellWindow::RunFileChooser(WebContents* tab, | 756 void AppWindow::RunFileChooser(WebContents* tab, |
| 772 const content::FileChooserParams& params) { | 757 const content::FileChooserParams& params) { |
| 773 if (window_type_is_panel()) { | 758 if (window_type_is_panel()) { |
| 774 // Panels can't host a file dialog, abort. TODO(stevenjb): allow file | 759 // Panels can't host a file dialog, abort. TODO(stevenjb): allow file |
| 775 // dialogs to be unhosted but still close with the owning web contents. | 760 // dialogs to be unhosted but still close with the owning web contents. |
| 776 // crbug.com/172502. | 761 // crbug.com/172502. |
| 777 LOG(WARNING) << "File dialog opened by panel."; | 762 LOG(WARNING) << "File dialog opened by panel."; |
| 778 return; | 763 return; |
| 779 } | 764 } |
| 780 | 765 |
| 781 delegate_->RunFileChooser(tab, params); | 766 delegate_->RunFileChooser(tab, params); |
| 782 } | 767 } |
| 783 | 768 |
| 784 bool ShellWindow::IsPopupOrPanel(const WebContents* source) const { | 769 bool AppWindow::IsPopupOrPanel(const WebContents* source) const { return true; } |
| 785 return true; | |
| 786 } | |
| 787 | 770 |
| 788 void ShellWindow::MoveContents(WebContents* source, const gfx::Rect& pos) { | 771 void AppWindow::MoveContents(WebContents* source, const gfx::Rect& pos) { |
| 789 native_app_window_->SetBounds(pos); | 772 native_app_window_->SetBounds(pos); |
| 790 } | 773 } |
| 791 | 774 |
| 792 void ShellWindow::NavigationStateChanged( | 775 void AppWindow::NavigationStateChanged(const content::WebContents* source, |
| 793 const content::WebContents* source, unsigned changed_flags) { | 776 unsigned changed_flags) { |
| 794 if (changed_flags & content::INVALIDATE_TYPE_TITLE) | 777 if (changed_flags & content::INVALIDATE_TYPE_TITLE) |
| 795 native_app_window_->UpdateWindowTitle(); | 778 native_app_window_->UpdateWindowTitle(); |
| 796 else if (changed_flags & content::INVALIDATE_TYPE_TAB) | 779 else if (changed_flags & content::INVALIDATE_TYPE_TAB) |
| 797 native_app_window_->UpdateWindowIcon(); | 780 native_app_window_->UpdateWindowIcon(); |
| 798 } | 781 } |
| 799 | 782 |
| 800 void ShellWindow::ToggleFullscreenModeForTab(content::WebContents* source, | 783 void AppWindow::ToggleFullscreenModeForTab(content::WebContents* source, |
| 801 bool enter_fullscreen) { | 784 bool enter_fullscreen) { |
| 802 #if !defined(OS_MACOSX) | 785 #if !defined(OS_MACOSX) |
| 803 // Do not enter fullscreen mode if disallowed by pref. | 786 // Do not enter fullscreen mode if disallowed by pref. |
| 804 // TODO(bartfab): Add a test once it becomes possible to simulate a user | 787 // TODO(bartfab): Add a test once it becomes possible to simulate a user |
| 805 // gesture. http://crbug.com/174178 | 788 // gesture. http://crbug.com/174178 |
| 806 PrefService* prefs = | 789 PrefService* prefs = |
| 807 extensions::ExtensionsBrowserClient::Get()->GetPrefServiceForContext( | 790 extensions::ExtensionsBrowserClient::Get()->GetPrefServiceForContext( |
| 808 browser_context()); | 791 browser_context()); |
| 809 if (enter_fullscreen && !prefs->GetBoolean(prefs::kAppFullscreenAllowed)) { | 792 if (enter_fullscreen && !prefs->GetBoolean(prefs::kAppFullscreenAllowed)) { |
| 810 return; | 793 return; |
| 811 } | 794 } |
| 812 #endif | 795 #endif |
| 813 | 796 |
| 814 if (!IsExtensionWithPermissionOrSuggestInConsole( | 797 if (!IsExtensionWithPermissionOrSuggestInConsole( |
| 815 APIPermission::kFullscreen, | 798 APIPermission::kFullscreen, |
| 816 extension_, | 799 extension_, |
| 817 source->GetRenderViewHost())) { | 800 source->GetRenderViewHost())) { |
| 818 return; | 801 return; |
| 819 } | 802 } |
| 820 | 803 |
| 821 if (enter_fullscreen) | 804 if (enter_fullscreen) |
| 822 fullscreen_types_ |= FULLSCREEN_TYPE_HTML_API; | 805 fullscreen_types_ |= FULLSCREEN_TYPE_HTML_API; |
| 823 else | 806 else |
| 824 fullscreen_types_ &= ~FULLSCREEN_TYPE_HTML_API; | 807 fullscreen_types_ &= ~FULLSCREEN_TYPE_HTML_API; |
| 825 SetNativeWindowFullscreen(); | 808 SetNativeWindowFullscreen(); |
| 826 } | 809 } |
| 827 | 810 |
| 828 bool ShellWindow::IsFullscreenForTabOrPending( | 811 bool AppWindow::IsFullscreenForTabOrPending(const content::WebContents* source) |
| 829 const content::WebContents* source) const { | 812 const { |
| 830 return ((fullscreen_types_ & FULLSCREEN_TYPE_HTML_API) != 0); | 813 return ((fullscreen_types_ & FULLSCREEN_TYPE_HTML_API) != 0); |
| 831 } | 814 } |
| 832 | 815 |
| 833 void ShellWindow::Observe(int type, | 816 void AppWindow::Observe(int type, |
| 834 const content::NotificationSource& source, | 817 const content::NotificationSource& source, |
| 835 const content::NotificationDetails& details) { | 818 const content::NotificationDetails& details) { |
| 836 switch (type) { | 819 switch (type) { |
| 837 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | 820 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
| 838 const extensions::Extension* unloaded_extension = | 821 const extensions::Extension* unloaded_extension = |
| 839 content::Details<extensions::UnloadedExtensionInfo>( | 822 content::Details<extensions::UnloadedExtensionInfo>(details) |
| 840 details)->extension; | 823 ->extension; |
| 841 if (extension_ == unloaded_extension) | 824 if (extension_ == unloaded_extension) |
| 842 native_app_window_->Close(); | 825 native_app_window_->Close(); |
| 843 break; | 826 break; |
| 844 } | 827 } |
| 845 case chrome::NOTIFICATION_APP_TERMINATING: | 828 case chrome::NOTIFICATION_APP_TERMINATING: |
| 846 native_app_window_->Close(); | 829 native_app_window_->Close(); |
| 847 break; | 830 break; |
| 848 default: | 831 default: |
| 849 NOTREACHED() << "Received unexpected notification"; | 832 NOTREACHED() << "Received unexpected notification"; |
| 850 } | 833 } |
| 851 } | 834 } |
| 852 | 835 |
| 853 void ShellWindow::SetWebContentsBlocked(content::WebContents* web_contents, | 836 void AppWindow::SetWebContentsBlocked(content::WebContents* web_contents, |
| 854 bool blocked) { | 837 bool blocked) { |
| 855 delegate_->SetWebContentsBlocked(web_contents, blocked); | 838 delegate_->SetWebContentsBlocked(web_contents, blocked); |
| 856 } | 839 } |
| 857 | 840 |
| 858 bool ShellWindow::IsWebContentsVisible(content::WebContents* web_contents) { | 841 bool AppWindow::IsWebContentsVisible(content::WebContents* web_contents) { |
| 859 return delegate_->IsWebContentsVisible(web_contents); | 842 return delegate_->IsWebContentsVisible(web_contents); |
| 860 } | 843 } |
| 861 | 844 |
| 862 extensions::ActiveTabPermissionGranter* | 845 extensions::ActiveTabPermissionGranter* |
| 863 ShellWindow::GetActiveTabPermissionGranter() { | 846 AppWindow::GetActiveTabPermissionGranter() { |
| 864 // Shell windows don't support the activeTab permission. | 847 // App windows don't support the activeTab permission. |
| 865 return NULL; | 848 return NULL; |
| 866 } | 849 } |
| 867 | 850 |
| 868 WebContentsModalDialogHost* ShellWindow::GetWebContentsModalDialogHost() { | 851 WebContentsModalDialogHost* AppWindow::GetWebContentsModalDialogHost() { |
| 869 return native_app_window_.get(); | 852 return native_app_window_.get(); |
| 870 } | 853 } |
| 871 | 854 |
| 872 void ShellWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level, | 855 void AppWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level, |
| 873 const std::string& message) { | 856 const std::string& message) { |
| 874 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); | 857 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); |
| 875 rvh->Send(new ExtensionMsg_AddMessageToConsole( | 858 rvh->Send(new ExtensionMsg_AddMessageToConsole( |
| 876 rvh->GetRoutingID(), level, message)); | 859 rvh->GetRoutingID(), level, message)); |
| 877 } | 860 } |
| 878 | 861 |
| 879 void ShellWindow::SaveWindowPosition() { | 862 void AppWindow::SaveWindowPosition() { |
| 880 if (window_key_.empty()) | 863 if (window_key_.empty()) |
| 881 return; | 864 return; |
| 882 if (!native_app_window_) | 865 if (!native_app_window_) |
| 883 return; | 866 return; |
| 884 | 867 |
| 885 ShellWindowGeometryCache* cache = | 868 AppWindowGeometryCache* cache = |
| 886 ShellWindowGeometryCache::Get(browser_context()); | 869 AppWindowGeometryCache::Get(browser_context()); |
| 887 | 870 |
| 888 gfx::Rect bounds = native_app_window_->GetRestoredBounds(); | 871 gfx::Rect bounds = native_app_window_->GetRestoredBounds(); |
| 889 bounds.Inset(native_app_window_->GetFrameInsets()); | 872 bounds.Inset(native_app_window_->GetFrameInsets()); |
| 890 gfx::Rect screen_bounds = | 873 gfx::Rect screen_bounds = |
| 891 gfx::Screen::GetNativeScreen()->GetDisplayMatching(bounds).work_area(); | 874 gfx::Screen::GetNativeScreen()->GetDisplayMatching(bounds).work_area(); |
| 892 ui::WindowShowState window_state = native_app_window_->GetRestoredState(); | 875 ui::WindowShowState window_state = native_app_window_->GetRestoredState(); |
| 893 cache->SaveGeometry(extension()->id(), | 876 cache->SaveGeometry( |
| 894 window_key_, | 877 extension()->id(), window_key_, bounds, screen_bounds, window_state); |
| 895 bounds, | |
| 896 screen_bounds, | |
| 897 window_state); | |
| 898 } | 878 } |
| 899 | 879 |
| 900 void ShellWindow::AdjustBoundsToBeVisibleOnScreen( | 880 void AppWindow::AdjustBoundsToBeVisibleOnScreen( |
| 901 const gfx::Rect& cached_bounds, | 881 const gfx::Rect& cached_bounds, |
| 902 const gfx::Rect& cached_screen_bounds, | 882 const gfx::Rect& cached_screen_bounds, |
| 903 const gfx::Rect& current_screen_bounds, | 883 const gfx::Rect& current_screen_bounds, |
| 904 const gfx::Size& minimum_size, | 884 const gfx::Size& minimum_size, |
| 905 gfx::Rect* bounds) const { | 885 gfx::Rect* bounds) const { |
| 906 *bounds = cached_bounds; | 886 *bounds = cached_bounds; |
| 907 | 887 |
| 908 // Reposition and resize the bounds if the cached_screen_bounds is different | 888 // Reposition and resize the bounds if the cached_screen_bounds is different |
| 909 // from the current screen bounds and the current screen bounds doesn't | 889 // from the current screen bounds and the current screen bounds doesn't |
| 910 // completely contain the bounds. | 890 // completely contain the bounds. |
| 911 if (cached_screen_bounds != current_screen_bounds && | 891 if (cached_screen_bounds != current_screen_bounds && |
| 912 !current_screen_bounds.Contains(cached_bounds)) { | 892 !current_screen_bounds.Contains(cached_bounds)) { |
| 913 bounds->set_width( | 893 bounds->set_width( |
| 914 std::max(minimum_size.width(), | 894 std::max(minimum_size.width(), |
| 915 std::min(bounds->width(), current_screen_bounds.width()))); | 895 std::min(bounds->width(), current_screen_bounds.width()))); |
| 916 bounds->set_height( | 896 bounds->set_height( |
| 917 std::max(minimum_size.height(), | 897 std::max(minimum_size.height(), |
| 918 std::min(bounds->height(), current_screen_bounds.height()))); | 898 std::min(bounds->height(), current_screen_bounds.height()))); |
| 919 bounds->set_x( | 899 bounds->set_x( |
| 920 std::max(current_screen_bounds.x(), | 900 std::max(current_screen_bounds.x(), |
| 921 std::min(bounds->x(), | 901 std::min(bounds->x(), |
| 922 current_screen_bounds.right() - bounds->width()))); | 902 current_screen_bounds.right() - bounds->width()))); |
| 923 bounds->set_y( | 903 bounds->set_y( |
| 924 std::max(current_screen_bounds.y(), | 904 std::max(current_screen_bounds.y(), |
| 925 std::min(bounds->y(), | 905 std::min(bounds->y(), |
| 926 current_screen_bounds.bottom() - bounds->height()))); | 906 current_screen_bounds.bottom() - bounds->height()))); |
| 927 } | 907 } |
| 928 } | 908 } |
| 929 | 909 |
| 930 ShellWindow::CreateParams ShellWindow::LoadDefaultsAndConstrain( | 910 AppWindow::CreateParams AppWindow::LoadDefaultsAndConstrain(CreateParams params) |
| 931 CreateParams params) const { | 911 const { |
| 932 if (params.bounds.width() == 0) | 912 if (params.bounds.width() == 0) |
| 933 params.bounds.set_width(kDefaultWidth); | 913 params.bounds.set_width(kDefaultWidth); |
| 934 if (params.bounds.height() == 0) | 914 if (params.bounds.height() == 0) |
| 935 params.bounds.set_height(kDefaultHeight); | 915 params.bounds.set_height(kDefaultHeight); |
| 936 | 916 |
| 937 // If left and top are left undefined, the native shell window will center | 917 // If left and top are left undefined, the native app window will center |
| 938 // the window on the main screen in a platform-defined manner. | 918 // the window on the main screen in a platform-defined manner. |
| 939 | 919 |
| 940 // Load cached state if it exists. | 920 // Load cached state if it exists. |
| 941 if (!params.window_key.empty()) { | 921 if (!params.window_key.empty()) { |
| 942 ShellWindowGeometryCache* cache = | 922 AppWindowGeometryCache* cache = |
| 943 ShellWindowGeometryCache::Get(browser_context()); | 923 AppWindowGeometryCache::Get(browser_context()); |
| 944 | 924 |
| 945 gfx::Rect cached_bounds; | 925 gfx::Rect cached_bounds; |
| 946 gfx::Rect cached_screen_bounds; | 926 gfx::Rect cached_screen_bounds; |
| 947 ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT; | 927 ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT; |
| 948 if (cache->GetGeometry(extension()->id(), params.window_key, | 928 if (cache->GetGeometry(extension()->id(), |
| 949 &cached_bounds, &cached_screen_bounds, | 929 params.window_key, |
| 930 &cached_bounds, |
| 931 &cached_screen_bounds, |
| 950 &cached_state)) { | 932 &cached_state)) { |
| 951 // App window has cached screen bounds, make sure it fits on screen in | 933 // App window has cached screen bounds, make sure it fits on screen in |
| 952 // case the screen resolution changed. | 934 // case the screen resolution changed. |
| 953 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | 935 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); |
| 954 gfx::Display display = screen->GetDisplayMatching(cached_bounds); | 936 gfx::Display display = screen->GetDisplayMatching(cached_bounds); |
| 955 gfx::Rect current_screen_bounds = display.work_area(); | 937 gfx::Rect current_screen_bounds = display.work_area(); |
| 956 AdjustBoundsToBeVisibleOnScreen(cached_bounds, | 938 AdjustBoundsToBeVisibleOnScreen(cached_bounds, |
| 957 cached_screen_bounds, | 939 cached_screen_bounds, |
| 958 current_screen_bounds, | 940 current_screen_bounds, |
| 959 params.minimum_size, | 941 params.minimum_size, |
| 960 ¶ms.bounds); | 942 ¶ms.bounds); |
| 961 params.state = cached_state; | 943 params.state = cached_state; |
| 962 } | 944 } |
| 963 } | 945 } |
| 964 | 946 |
| 965 SizeConstraints size_constraints(params.minimum_size, params.maximum_size); | 947 SizeConstraints size_constraints(params.minimum_size, params.maximum_size); |
| 966 params.bounds.set_size(size_constraints.ClampSize(params.bounds.size())); | 948 params.bounds.set_size(size_constraints.ClampSize(params.bounds.size())); |
| 967 params.minimum_size = size_constraints.GetMinimumSize(); | 949 params.minimum_size = size_constraints.GetMinimumSize(); |
| 968 params.maximum_size = size_constraints.GetMaximumSize(); | 950 params.maximum_size = size_constraints.GetMaximumSize(); |
| 969 | 951 |
| 970 return params; | 952 return params; |
| 971 } | 953 } |
| 972 | 954 |
| 973 // static | 955 // static |
| 974 SkRegion* ShellWindow::RawDraggableRegionsToSkRegion( | 956 SkRegion* AppWindow::RawDraggableRegionsToSkRegion( |
| 975 const std::vector<extensions::DraggableRegion>& regions) { | 957 const std::vector<extensions::DraggableRegion>& regions) { |
| 976 SkRegion* sk_region = new SkRegion; | 958 SkRegion* sk_region = new SkRegion; |
| 977 for (std::vector<extensions::DraggableRegion>::const_iterator iter = | 959 for (std::vector<extensions::DraggableRegion>::const_iterator iter = |
| 978 regions.begin(); | 960 regions.begin(); |
| 979 iter != regions.end(); ++iter) { | 961 iter != regions.end(); |
| 962 ++iter) { |
| 980 const extensions::DraggableRegion& region = *iter; | 963 const extensions::DraggableRegion& region = *iter; |
| 981 sk_region->op( | 964 sk_region->op( |
| 982 region.bounds.x(), | 965 region.bounds.x(), |
| 983 region.bounds.y(), | 966 region.bounds.y(), |
| 984 region.bounds.right(), | 967 region.bounds.right(), |
| 985 region.bounds.bottom(), | 968 region.bounds.bottom(), |
| 986 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); | 969 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); |
| 987 } | 970 } |
| 988 return sk_region; | 971 return sk_region; |
| 989 } | 972 } |
| 990 | 973 |
| 991 } // namespace apps | 974 } // namespace apps |
| OLD | NEW |