Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Side by Side Diff: apps/shell_window.cc

Issue 55293003: Defer app window appearance until first paint. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix merge issue Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « apps/shell_window.h ('k') | chrome/app/generated_resources.grd » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/shell_window.h"
6 6
7 #include "apps/shell_window_geometry_cache.h" 7 #include "apps/shell_window_geometry_cache.h"
8 #include "apps/shell_window_registry.h" 8 #include "apps/shell_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/strings/string_util.h" 11 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h" 13 #include "base/values.h"
13 #include "chrome/browser/chrome_notification_types.h" 14 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/extensions/extension_process_manager.h" 15 #include "chrome/browser/extensions/extension_process_manager.h"
15 #include "chrome/browser/extensions/extension_system.h" 16 #include "chrome/browser/extensions/extension_system.h"
16 #include "chrome/browser/extensions/extension_web_contents_observer.h" 17 #include "chrome/browser/extensions/extension_web_contents_observer.h"
17 #include "chrome/browser/extensions/suggest_permission_util.h" 18 #include "chrome/browser/extensions/suggest_permission_util.h"
18 #include "chrome/browser/lifetime/application_lifetime.h" 19 #include "chrome/browser/lifetime/application_lifetime.h"
19 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/extensions/extension.h" 22 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/extensions/extension_messages.h" 23 #include "chrome/common/extensions/extension_messages.h"
22 #include "chrome/common/extensions/manifest_handlers/icons_handler.h" 24 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
23 #include "components/web_modal/web_contents_modal_dialog_manager.h" 25 #include "components/web_modal/web_contents_modal_dialog_manager.h"
24 #include "content/public/browser/invalidate_type.h" 26 #include "content/public/browser/invalidate_type.h"
25 #include "content/public/browser/navigation_entry.h" 27 #include "content/public/browser/navigation_entry.h"
26 #include "content/public/browser/notification_details.h" 28 #include "content/public/browser/notification_details.h"
27 #include "content/public/browser/notification_service.h" 29 #include "content/public/browser/notification_service.h"
28 #include "content/public/browser/notification_source.h" 30 #include "content/public/browser/notification_source.h"
29 #include "content/public/browser/notification_types.h" 31 #include "content/public/browser/notification_types.h"
30 #include "content/public/browser/render_view_host.h" 32 #include "content/public/browser/render_view_host.h"
31 #include "content/public/browser/resource_dispatcher_host.h" 33 #include "content/public/browser/resource_dispatcher_host.h"
32 #include "content/public/browser/web_contents.h" 34 #include "content/public/browser/web_contents.h"
35 #include "content/public/browser/web_contents_view.h"
33 #include "content/public/common/media_stream_request.h" 36 #include "content/public/common/media_stream_request.h"
34 #include "extensions/browser/view_type_utils.h" 37 #include "extensions/browser/view_type_utils.h"
35 #include "third_party/skia/include/core/SkRegion.h" 38 #include "third_party/skia/include/core/SkRegion.h"
36 #include "ui/gfx/screen.h" 39 #include "ui/gfx/screen.h"
37 40
38 #if !defined(OS_MACOSX) 41 #if !defined(OS_MACOSX)
39 #include "apps/pref_names.h" 42 #include "apps/pref_names.h"
40 #include "base/prefs/pref_service.h" 43 #include "base/prefs/pref_service.h"
41 #endif 44 #endif
42 45
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 ShellWindow::ShellWindow(Profile* profile, 135 ShellWindow::ShellWindow(Profile* profile,
133 Delegate* delegate, 136 Delegate* delegate,
134 const extensions::Extension* extension) 137 const extensions::Extension* extension)
135 : profile_(profile), 138 : profile_(profile),
136 extension_(extension), 139 extension_(extension),
137 extension_id_(extension->id()), 140 extension_id_(extension->id()),
138 window_type_(WINDOW_TYPE_DEFAULT), 141 window_type_(WINDOW_TYPE_DEFAULT),
139 delegate_(delegate), 142 delegate_(delegate),
140 image_loader_ptr_factory_(this), 143 image_loader_ptr_factory_(this),
141 fullscreen_for_window_api_(false), 144 fullscreen_for_window_api_(false),
142 fullscreen_for_tab_(false) { 145 fullscreen_for_tab_(false),
146 show_on_first_paint_(false),
147 first_paint_complete_(false) {
143 } 148 }
144 149
145 void ShellWindow::Init(const GURL& url, 150 void ShellWindow::Init(const GURL& url,
146 ShellWindowContents* shell_window_contents, 151 ShellWindowContents* shell_window_contents,
147 const CreateParams& params) { 152 const CreateParams& params) {
148 // Initialize the render interface and web contents 153 // Initialize the render interface and web contents
149 shell_window_contents_.reset(shell_window_contents); 154 shell_window_contents_.reset(shell_window_contents);
150 shell_window_contents_->Initialize(profile(), url); 155 shell_window_contents_->Initialize(profile(), url);
151 WebContents* web_contents = shell_window_contents_->GetWebContents(); 156 WebContents* web_contents = shell_window_contents_->GetWebContents();
157 if (CommandLine::ForCurrentProcess()->HasSwitch(
158 switches::kEnableAppsShowOnFirstPaint)) {
159 content::WebContentsObserver::Observe(web_contents);
160 }
152 delegate_->InitWebContents(web_contents); 161 delegate_->InitWebContents(web_contents);
153 WebContentsModalDialogManager::CreateForWebContents(web_contents); 162 WebContentsModalDialogManager::CreateForWebContents(web_contents);
154 extensions::ExtensionWebContentsObserver::CreateForWebContents(web_contents); 163 extensions::ExtensionWebContentsObserver::CreateForWebContents(web_contents);
155 164
156 web_contents->SetDelegate(this); 165 web_contents->SetDelegate(this);
157 WebContentsModalDialogManager::FromWebContents(web_contents)-> 166 WebContentsModalDialogManager::FromWebContents(web_contents)->
158 SetDelegate(this); 167 SetDelegate(this);
159 extensions::SetViewType(web_contents, extensions::VIEW_TYPE_APP_SHELL); 168 extensions::SetViewType(web_contents, extensions::VIEW_TYPE_APP_SHELL);
160 169
161 // Initialize the window 170 // Initialize the window
162 CreateParams new_params = LoadDefaultsAndConstrain(params); 171 CreateParams new_params = LoadDefaultsAndConstrain(params);
163 window_type_ = new_params.window_type; 172 window_type_ = new_params.window_type;
164 window_key_ = new_params.window_key; 173 window_key_ = new_params.window_key;
165 size_constraints_ = SizeConstraints(new_params.minimum_size, 174 size_constraints_ = SizeConstraints(new_params.minimum_size,
166 new_params.maximum_size); 175 new_params.maximum_size);
167 native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params)); 176 native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params));
168 177
169 if (!new_params.hidden) { 178 if (!new_params.hidden) {
170 if (window_type_is_panel()) 179 // Panels are not activated by default.
171 GetBaseWindow()->ShowInactive(); // Panels are not activated by default. 180 Show(window_type_is_panel() ? SHOW_INACTIVE : SHOW_ACTIVE);
172 else
173 GetBaseWindow()->Show();
174 } 181 }
175 182
176 if (new_params.state == ui::SHOW_STATE_FULLSCREEN) 183 if (new_params.state == ui::SHOW_STATE_FULLSCREEN)
177 Fullscreen(); 184 Fullscreen();
178 else if (new_params.state == ui::SHOW_STATE_MAXIMIZED) 185 else if (new_params.state == ui::SHOW_STATE_MAXIMIZED)
179 Maximize(); 186 Maximize();
180 else if (new_params.state == ui::SHOW_STATE_MINIMIZED) 187 else if (new_params.state == ui::SHOW_STATE_MINIMIZED)
181 Minimize(); 188 Minimize();
182 189
183 OnNativeWindowChanged(); 190 OnNativeWindowChanged();
184 191
185 // When the render view host is changed, the native window needs to know 192 // When the render view host is changed, the native window needs to know
186 // about it in case it has any setup to do to make the renderer appear 193 // about it in case it has any setup to do to make the renderer appear
187 // properly. In particular, on Windows, the view's clickthrough region needs 194 // properly. In particular, on Windows, the view's clickthrough region needs
188 // to be set. 195 // to be set.
189 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 196 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
190 content::Source<Profile>(profile_)); 197 content::Source<Profile>(profile_));
191 // Close when the browser process is exiting. 198 // Close when the browser process is exiting.
192 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, 199 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
193 content::NotificationService::AllSources()); 200 content::NotificationService::AllSources());
194 201
195 shell_window_contents_->LoadContents(new_params.creator_process_id); 202 shell_window_contents_->LoadContents(new_params.creator_process_id);
196 203
204 if (CommandLine::ForCurrentProcess()->HasSwitch(
205 switches::kEnableAppsShowOnFirstPaint)) {
206 // We want to show the window only when the content has been painted. For
207 // that to happen, we need to define a size for the content, otherwise the
208 // layout will happen in a 0x0 area.
209 // Note: WebContents::GetView() is guaranteed to be non-null.
210 web_contents->GetView()->SizeContents(new_params.bounds.size());
211 }
212
197 // Prevent the browser process from shutting down while this window is open. 213 // Prevent the browser process from shutting down while this window is open.
198 chrome::StartKeepAlive(); 214 chrome::StartKeepAlive();
199 215
200 UpdateExtensionAppIcon(); 216 UpdateExtensionAppIcon();
201 217
202 ShellWindowRegistry::Get(profile_)->AddShellWindow(this); 218 ShellWindowRegistry::Get(profile_)->AddShellWindow(this);
203 } 219 }
204 220
205 ShellWindow::~ShellWindow() { 221 ShellWindow::~ShellWindow() {
206 // Unregister now to prevent getting NOTIFICATION_APP_TERMINATING if we're the 222 // Unregister now to prevent getting NOTIFICATION_APP_TERMINATING if we're the
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 bool user_gesture, 293 bool user_gesture,
278 bool last_unlocked_by_target) { 294 bool last_unlocked_by_target) {
279 bool has_permission = IsExtensionWithPermissionOrSuggestInConsole( 295 bool has_permission = IsExtensionWithPermissionOrSuggestInConsole(
280 APIPermission::kPointerLock, 296 APIPermission::kPointerLock,
281 extension_, 297 extension_,
282 web_contents->GetRenderViewHost()); 298 web_contents->GetRenderViewHost());
283 299
284 web_contents->GotResponseToLockMouseRequest(has_permission); 300 web_contents->GotResponseToLockMouseRequest(has_permission);
285 } 301 }
286 302
303 void ShellWindow::DidFirstVisuallyNonEmptyPaint(int32 page_id) {
304 first_paint_complete_ = true;
305 if (show_on_first_paint_) {
306 DCHECK(delayed_show_type_ == SHOW_ACTIVE ||
307 delayed_show_type_ == SHOW_INACTIVE);
308 Show(delayed_show_type_);
309 }
310 }
311
287 void ShellWindow::OnNativeClose() { 312 void ShellWindow::OnNativeClose() {
288 ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this); 313 ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this);
289 if (shell_window_contents_) { 314 if (shell_window_contents_) {
290 WebContents* web_contents = shell_window_contents_->GetWebContents(); 315 WebContents* web_contents = shell_window_contents_->GetWebContents();
291 WebContentsModalDialogManager::FromWebContents(web_contents)-> 316 WebContentsModalDialogManager::FromWebContents(web_contents)->
292 SetDelegate(NULL); 317 SetDelegate(NULL);
293 shell_window_contents_->NativeWindowClosed(); 318 shell_window_contents_->NativeWindowClosed();
294 } 319 }
295 delete this; 320 delete this;
296 } 321 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 void ShellWindow::SetMinimumSize(const gfx::Size& min_size) { 429 void ShellWindow::SetMinimumSize(const gfx::Size& min_size) {
405 size_constraints_.set_minimum_size(min_size); 430 size_constraints_.set_minimum_size(min_size);
406 OnSizeConstraintsChanged(); 431 OnSizeConstraintsChanged();
407 } 432 }
408 433
409 void ShellWindow::SetMaximumSize(const gfx::Size& max_size) { 434 void ShellWindow::SetMaximumSize(const gfx::Size& max_size) {
410 size_constraints_.set_maximum_size(max_size); 435 size_constraints_.set_maximum_size(max_size);
411 OnSizeConstraintsChanged(); 436 OnSizeConstraintsChanged();
412 } 437 }
413 438
439 void ShellWindow::Show(ShowType show_type) {
440 if (CommandLine::ForCurrentProcess()->HasSwitch(
441 switches::kEnableAppsShowOnFirstPaint)) {
442 show_on_first_paint_ = true;
443
444 if (!first_paint_complete_) {
445 delayed_show_type_ = show_type;
446 return;
447 }
448 }
449
450 switch (show_type) {
451 case SHOW_ACTIVE:
452 GetBaseWindow()->Show();
453 break;
454 case SHOW_INACTIVE:
455 GetBaseWindow()->ShowInactive();
456 break;
457 }
458 }
459
460 void ShellWindow::Hide() {
461 // This is there to prevent race conditions with Hide() being called before
462 // there was a non-empty paint. It should have no effect in a non-racy
463 // scenario where the application is hiding then showing a window: the second
464 // show will not be delayed.
465 show_on_first_paint_ = false;
466 GetBaseWindow()->Hide();
467 }
468
414 //------------------------------------------------------------------------------ 469 //------------------------------------------------------------------------------
415 // Private methods 470 // Private methods
416 471
417 void ShellWindow::DidDownloadFavicon( 472 void ShellWindow::DidDownloadFavicon(
418 int id, 473 int id,
419 int http_status_code, 474 int http_status_code,
420 const GURL& image_url, 475 const GURL& image_url,
421 const std::vector<SkBitmap>& bitmaps, 476 const std::vector<SkBitmap>& bitmaps,
422 const std::vector<gfx::Size>& original_bitmap_sizes) { 477 const std::vector<gfx::Size>& original_bitmap_sizes) {
423 if (image_url != app_icon_url_ || bitmaps.empty()) 478 if (image_url != app_icon_url_ || bitmaps.empty())
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 region.bounds.x(), 749 region.bounds.x(),
695 region.bounds.y(), 750 region.bounds.y(),
696 region.bounds.right(), 751 region.bounds.right(),
697 region.bounds.bottom(), 752 region.bounds.bottom(),
698 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); 753 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
699 } 754 }
700 return sk_region; 755 return sk_region;
701 } 756 }
702 757
703 } // namespace apps 758 } // namespace apps
OLDNEW
« no previous file with comments | « apps/shell_window.h ('k') | chrome/app/generated_resources.grd » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698