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

Side by Side Diff: extensions/browser/app_window/app_window.cc

Issue 2553263002: Remove code to defer app window appearance until first paint. (Closed)
Patch Set: nit Created 4 years 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "extensions/browser/app_window/app_window.h" 5 #include "extensions/browser/app_window/app_window.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
11 #include <utility> 11 #include <utility>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
15 #include "base/command_line.h"
16 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
17 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
18 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
19 #include "base/task_runner.h" 18 #include "base/task_runner.h"
20 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
21 #include "base/values.h" 20 #include "base/values.h"
22 #include "build/build_config.h" 21 #include "build/build_config.h"
23 #include "components/web_modal/web_contents_modal_dialog_manager.h" 22 #include "components/web_modal/web_contents_modal_dialog_manager.h"
24 #include "content/public/browser/browser_context.h" 23 #include "content/public/browser/browser_context.h"
25 #include "content/public/browser/invalidate_type.h" 24 #include "content/public/browser/invalidate_type.h"
26 #include "content/public/browser/navigation_entry.h" 25 #include "content/public/browser/navigation_entry.h"
27 #include "content/public/browser/render_view_host.h" 26 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/render_widget_host.h" 27 #include "content/public/browser/render_widget_host.h"
29 #include "content/public/browser/resource_dispatcher_host.h" 28 #include "content/public/browser/resource_dispatcher_host.h"
30 #include "content/public/browser/web_contents.h" 29 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/browser_side_navigation_policy.h" 30 #include "content/public/common/browser_side_navigation_policy.h"
32 #include "content/public/common/content_switches.h"
33 #include "content/public/common/media_stream_request.h" 31 #include "content/public/common/media_stream_request.h"
34 #include "extensions/browser/app_window/app_delegate.h" 32 #include "extensions/browser/app_window/app_delegate.h"
35 #include "extensions/browser/app_window/app_web_contents_helper.h" 33 #include "extensions/browser/app_window/app_web_contents_helper.h"
36 #include "extensions/browser/app_window/app_window_client.h" 34 #include "extensions/browser/app_window/app_window_client.h"
37 #include "extensions/browser/app_window/app_window_geometry_cache.h" 35 #include "extensions/browser/app_window/app_window_geometry_cache.h"
38 #include "extensions/browser/app_window/app_window_registry.h" 36 #include "extensions/browser/app_window/app_window_registry.h"
39 #include "extensions/browser/app_window/native_app_window.h" 37 #include "extensions/browser/app_window/native_app_window.h"
40 #include "extensions/browser/app_window/size_constraints.h" 38 #include "extensions/browser/app_window/size_constraints.h"
41 #include "extensions/browser/extension_registry.h" 39 #include "extensions/browser/extension_registry.h"
42 #include "extensions/browser/extension_system.h" 40 #include "extensions/browser/extension_system.h"
43 #include "extensions/browser/extension_web_contents_observer.h" 41 #include "extensions/browser/extension_web_contents_observer.h"
44 #include "extensions/browser/extensions_browser_client.h" 42 #include "extensions/browser/extensions_browser_client.h"
45 #include "extensions/browser/notification_types.h" 43 #include "extensions/browser/notification_types.h"
46 #include "extensions/browser/process_manager.h" 44 #include "extensions/browser/process_manager.h"
47 #include "extensions/browser/suggest_permission_util.h" 45 #include "extensions/browser/suggest_permission_util.h"
48 #include "extensions/browser/view_type_utils.h" 46 #include "extensions/browser/view_type_utils.h"
49 #include "extensions/common/draggable_region.h" 47 #include "extensions/common/draggable_region.h"
50 #include "extensions/common/extension.h" 48 #include "extensions/common/extension.h"
51 #include "extensions/common/manifest_handlers/icons_handler.h" 49 #include "extensions/common/manifest_handlers/icons_handler.h"
52 #include "extensions/common/permissions/permissions_data.h" 50 #include "extensions/common/permissions/permissions_data.h"
53 #include "extensions/common/switches.h"
54 #include "extensions/grit/extensions_browser_resources.h" 51 #include "extensions/grit/extensions_browser_resources.h"
55 #include "third_party/skia/include/core/SkRegion.h" 52 #include "third_party/skia/include/core/SkRegion.h"
56 #include "ui/base/resource/resource_bundle.h" 53 #include "ui/base/resource/resource_bundle.h"
57 #include "ui/display/display.h" 54 #include "ui/display/display.h"
58 #include "ui/display/screen.h" 55 #include "ui/display/screen.h"
59 #include "ui/events/keycodes/keyboard_codes.h" 56 #include "ui/events/keycodes/keyboard_codes.h"
60 #include "ui/gfx/image/image_skia_operations.h" 57 #include "ui/gfx/image/image_skia_operations.h"
61 58
62 #if !defined(OS_MACOSX) 59 #if !defined(OS_MACOSX)
63 #include "components/prefs/pref_service.h" 60 #include "components/prefs/pref_service.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 // AppWindow 237 // AppWindow
241 238
242 AppWindow::AppWindow(BrowserContext* context, 239 AppWindow::AppWindow(BrowserContext* context,
243 AppDelegate* app_delegate, 240 AppDelegate* app_delegate,
244 const Extension* extension) 241 const Extension* extension)
245 : browser_context_(context), 242 : browser_context_(context),
246 extension_id_(extension->id()), 243 extension_id_(extension->id()),
247 window_type_(WINDOW_TYPE_DEFAULT), 244 window_type_(WINDOW_TYPE_DEFAULT),
248 app_delegate_(app_delegate), 245 app_delegate_(app_delegate),
249 fullscreen_types_(FULLSCREEN_TYPE_NONE), 246 fullscreen_types_(FULLSCREEN_TYPE_NONE),
250 show_on_first_paint_(false),
251 first_paint_complete_(false),
252 has_been_shown_(false), 247 has_been_shown_(false),
253 can_send_events_(false),
254 is_hidden_(false), 248 is_hidden_(false),
255 delayed_show_type_(SHOW_ACTIVE),
256 cached_always_on_top_(false), 249 cached_always_on_top_(false),
257 requested_alpha_enabled_(false), 250 requested_alpha_enabled_(false),
258 is_ime_window_(false), 251 is_ime_window_(false),
259 show_in_shelf_(false), 252 show_in_shelf_(false),
260 image_loader_ptr_factory_(this) { 253 image_loader_ptr_factory_(this) {
261 ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); 254 ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get();
262 CHECK(!client->IsGuestSession(context) || context->IsOffTheRecord()) 255 CHECK(!client->IsGuestSession(context) || context->IsOffTheRecord())
263 << "Only off the record window may be opened in the guest mode."; 256 << "Only off the record window may be opened in the guest mode.";
264 } 257 }
265 258
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 OnNativeWindowChanged(); 337 OnNativeWindowChanged();
345 338
346 ExtensionRegistry::Get(browser_context_)->AddObserver(this); 339 ExtensionRegistry::Get(browser_context_)->AddObserver(this);
347 340
348 // Close when the browser process is exiting. 341 // Close when the browser process is exiting.
349 app_delegate_->SetTerminatingCallback( 342 app_delegate_->SetTerminatingCallback(
350 base::Bind(&NativeAppWindow::Close, 343 base::Bind(&NativeAppWindow::Close,
351 base::Unretained(native_app_window_.get()))); 344 base::Unretained(native_app_window_.get())));
352 345
353 app_window_contents_->LoadContents(new_params.creator_process_id); 346 app_window_contents_->LoadContents(new_params.creator_process_id);
354
355 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
356 extensions::switches::kEnableAppsShowOnFirstPaint)) {
357 // We want to show the window only when the content has been painted. For
358 // that to happen, we need to define a size for the content, otherwise the
359 // layout will happen in a 0x0 area.
360 gfx::Insets frame_insets = native_app_window_->GetFrameInsets();
361 gfx::Rect initial_bounds = new_params.GetInitialWindowBounds(frame_insets);
362 initial_bounds.Inset(frame_insets);
363 app_delegate_->ResizeWebContents(web_contents(), initial_bounds.size());
364 }
365 } 347 }
366 348
367 AppWindow::~AppWindow() { 349 AppWindow::~AppWindow() {
368 ExtensionRegistry::Get(browser_context_)->RemoveObserver(this); 350 ExtensionRegistry::Get(browser_context_)->RemoveObserver(this);
369 } 351 }
370 352
371 void AppWindow::RequestMediaAccessPermission( 353 void AppWindow::RequestMediaAccessPermission(
372 content::WebContents* web_contents, 354 content::WebContents* web_contents,
373 const content::MediaStreamRequest& request, 355 const content::MediaStreamRequest& request,
374 const content::MediaResponseCallback& callback) { 356 const content::MediaResponseCallback& callback) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 content::RenderFrameHost* frame, 444 content::RenderFrameHost* frame,
463 const content::BluetoothChooser::EventHandler& event_handler) { 445 const content::BluetoothChooser::EventHandler& event_handler) {
464 return ExtensionsBrowserClient::Get()->CreateBluetoothChooser(frame, 446 return ExtensionsBrowserClient::Get()->CreateBluetoothChooser(frame,
465 event_handler); 447 event_handler);
466 } 448 }
467 449
468 void AppWindow::RenderViewCreated(content::RenderViewHost* render_view_host) { 450 void AppWindow::RenderViewCreated(content::RenderViewHost* render_view_host) {
469 app_delegate_->RenderViewCreated(render_view_host); 451 app_delegate_->RenderViewCreated(render_view_host);
470 } 452 }
471 453
472 void AppWindow::DidFirstVisuallyNonEmptyPaint() {
473 first_paint_complete_ = true;
474 if (show_on_first_paint_) {
475 DCHECK(delayed_show_type_ == SHOW_ACTIVE ||
476 delayed_show_type_ == SHOW_INACTIVE);
477 Show(delayed_show_type_);
478 }
479 }
480
481 void AppWindow::SetOnFirstCommitCallback(const base::Closure& callback) { 454 void AppWindow::SetOnFirstCommitCallback(const base::Closure& callback) {
482 DCHECK(on_first_commit_callback_.is_null()); 455 DCHECK(on_first_commit_callback_.is_null());
483 on_first_commit_callback_ = callback; 456 on_first_commit_callback_ = callback;
484 } 457 }
485 458
486 void AppWindow::OnReadyToCommitFirstNavigation() { 459 void AppWindow::OnReadyToCommitFirstNavigation() {
487 if (!content::IsBrowserSideNavigationEnabled()) 460 if (!content::IsBrowserSideNavigationEnabled())
488 return; 461 return;
489 462
490 // PlzNavigate: execute renderer-side setup now that there is a renderer 463 // PlzNavigate: execute renderer-side setup now that there is a renderer
491 // process assigned to the navigation. With renderer-side navigation, this 464 // process assigned to the navigation. With renderer-side navigation, this
492 // would happen before the navigation starts, but PlzNavigate must wait until 465 // would happen before the navigation starts, but PlzNavigate must wait until
493 // this point in time in the navigation. 466 // this point in time in the navigation.
494 467
495 WindowEventsReady();
496 if (on_first_commit_callback_.is_null()) 468 if (on_first_commit_callback_.is_null())
497 return; 469 return;
498 // It is important that the callback executes after the calls to 470 // It is important that the callback executes after the calls to
499 // WebContentsObserver::ReadyToCommitNavigation have been processed. The 471 // WebContentsObserver::ReadyToCommitNavigation have been processed. The
500 // CommitNavigation IPC that will properly set up the renderer will only be 472 // CommitNavigation IPC that will properly set up the renderer will only be
501 // sent after these, and it must be sent before the callback gets to run, 473 // sent after these, and it must be sent before the callback gets to run,
502 // hence the use of PostTask. 474 // hence the use of PostTask.
503 base::ThreadTaskRunnerHandle::Get()->PostTask( 475 base::ThreadTaskRunnerHandle::Get()->PostTask(
504 FROM_HERE, base::ResetAndReturn(&on_first_commit_callback_)); 476 FROM_HERE, base::ResetAndReturn(&on_first_commit_callback_));
505 } 477 }
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 native_app_window_->SetBounds(bounds); 690 native_app_window_->SetBounds(bounds);
719 } 691 }
720 OnNativeWindowChanged(); 692 OnNativeWindowChanged();
721 } 693 }
722 694
723 void AppWindow::Show(ShowType show_type) { 695 void AppWindow::Show(ShowType show_type) {
724 app_delegate_->OnShow(); 696 app_delegate_->OnShow();
725 bool was_hidden = is_hidden_ || !has_been_shown_; 697 bool was_hidden = is_hidden_ || !has_been_shown_;
726 is_hidden_ = false; 698 is_hidden_ = false;
727 699
728 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
729 switches::kEnableAppsShowOnFirstPaint)) {
730 show_on_first_paint_ = true;
731
732 if (!first_paint_complete_) {
733 delayed_show_type_ = show_type;
734 return;
735 }
736 }
737
738 switch (show_type) { 700 switch (show_type) {
739 case SHOW_ACTIVE: 701 case SHOW_ACTIVE:
740 GetBaseWindow()->Show(); 702 GetBaseWindow()->Show();
741 break; 703 break;
742 case SHOW_INACTIVE: 704 case SHOW_INACTIVE:
743 GetBaseWindow()->ShowInactive(); 705 GetBaseWindow()->ShowInactive();
744 break; 706 break;
745 } 707 }
746 AppWindowRegistry::Get(browser_context_)->AppWindowShown(this, was_hidden); 708 AppWindowRegistry::Get(browser_context_)->AppWindowShown(this, was_hidden);
747
748 has_been_shown_ = true; 709 has_been_shown_ = true;
749 SendOnWindowShownIfShown();
750 } 710 }
751 711
752 void AppWindow::Hide() { 712 void AppWindow::Hide() {
753 // This is there to prevent race conditions with Hide() being called before
754 // there was a non-empty paint. It should have no effect in a non-racy
755 // scenario where the application is hiding then showing a window: the second
756 // show will not be delayed.
757 is_hidden_ = true; 713 is_hidden_ = true;
758 show_on_first_paint_ = false;
759 GetBaseWindow()->Hide(); 714 GetBaseWindow()->Hide();
760 AppWindowRegistry::Get(browser_context_)->AppWindowHidden(this); 715 AppWindowRegistry::Get(browser_context_)->AppWindowHidden(this);
761 app_delegate_->OnHide(); 716 app_delegate_->OnHide();
762 } 717 }
763 718
764 void AppWindow::SetAlwaysOnTop(bool always_on_top) { 719 void AppWindow::SetAlwaysOnTop(bool always_on_top) {
765 if (cached_always_on_top_ == always_on_top) 720 if (cached_always_on_top_ == always_on_top)
766 return; 721 return;
767 722
768 cached_always_on_top_ = always_on_top; 723 cached_always_on_top_ = always_on_top;
769 724
770 // As a security measure, do not allow fullscreen windows or windows that 725 // As a security measure, do not allow fullscreen windows or windows that
771 // overlap the taskbar to be on top. The property will be applied when the 726 // overlap the taskbar to be on top. The property will be applied when the
772 // window exits fullscreen and moves away from the taskbar. 727 // window exits fullscreen and moves away from the taskbar.
773 if (!IsFullscreen() && !IntersectsWithTaskbar()) 728 if (!IsFullscreen() && !IntersectsWithTaskbar())
774 native_app_window_->SetAlwaysOnTop(always_on_top); 729 native_app_window_->SetAlwaysOnTop(always_on_top);
775 730
776 OnNativeWindowChanged(); 731 OnNativeWindowChanged();
777 } 732 }
778 733
779 bool AppWindow::IsAlwaysOnTop() const { return cached_always_on_top_; } 734 bool AppWindow::IsAlwaysOnTop() const { return cached_always_on_top_; }
780 735
781 void AppWindow::RestoreAlwaysOnTop() { 736 void AppWindow::RestoreAlwaysOnTop() {
782 if (cached_always_on_top_) 737 if (cached_always_on_top_)
783 UpdateNativeAlwaysOnTop(); 738 UpdateNativeAlwaysOnTop();
784 } 739 }
785 740
786 void AppWindow::WindowEventsReady() {
787 can_send_events_ = true;
788 SendOnWindowShownIfShown();
789 }
790
791 void AppWindow::NotifyRenderViewReady() { 741 void AppWindow::NotifyRenderViewReady() {
792 if (app_window_contents_) 742 if (app_window_contents_)
793 app_window_contents_->OnWindowReady(); 743 app_window_contents_->OnWindowReady();
794 } 744 }
795 745
796 void AppWindow::GetSerializedState(base::DictionaryValue* properties) const { 746 void AppWindow::GetSerializedState(base::DictionaryValue* properties) const {
797 DCHECK(properties); 747 DCHECK(properties);
798 748
799 properties->SetBoolean("fullscreen", 749 properties->SetBoolean("fullscreen",
800 native_app_window_->IsFullscreenOrPending()); 750 native_app_window_->IsFullscreenOrPending());
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 // When entering fullscreen or overlapping the taskbar, ensure windows are 882 // When entering fullscreen or overlapping the taskbar, ensure windows are
933 // not always-on-top. 883 // not always-on-top.
934 native_app_window_->SetAlwaysOnTop(false); 884 native_app_window_->SetAlwaysOnTop(false);
935 } else if (!is_on_top && !fullscreen && !intersects_taskbar) { 885 } else if (!is_on_top && !fullscreen && !intersects_taskbar) {
936 // When exiting fullscreen and moving away from the taskbar, reinstate 886 // When exiting fullscreen and moving away from the taskbar, reinstate
937 // always-on-top. 887 // always-on-top.
938 native_app_window_->SetAlwaysOnTop(true); 888 native_app_window_->SetAlwaysOnTop(true);
939 } 889 }
940 } 890 }
941 891
942 void AppWindow::SendOnWindowShownIfShown() {
943 if (!can_send_events_ || !has_been_shown_)
944 return;
945
946 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
947 ::switches::kTestType)) {
948 app_window_contents_->DispatchWindowShownForTests();
949 }
950 }
951
952 void AppWindow::CloseContents(WebContents* contents) { 892 void AppWindow::CloseContents(WebContents* contents) {
953 native_app_window_->Close(); 893 native_app_window_->Close();
954 } 894 }
955 895
956 bool AppWindow::ShouldSuppressDialogs(WebContents* source) { 896 bool AppWindow::ShouldSuppressDialogs(WebContents* source) {
957 return true; 897 return true;
958 } 898 }
959 899
960 content::ColorChooser* AppWindow::OpenColorChooser( 900 content::ColorChooser* AppWindow::OpenColorChooser(
961 WebContents* web_contents, 901 WebContents* web_contents,
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 region.bounds.x(), 1102 region.bounds.x(),
1163 region.bounds.y(), 1103 region.bounds.y(),
1164 region.bounds.right(), 1104 region.bounds.right(),
1165 region.bounds.bottom(), 1105 region.bounds.bottom(),
1166 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); 1106 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
1167 } 1107 }
1168 return sk_region; 1108 return sk_region;
1169 } 1109 }
1170 1110
1171 } // namespace extensions 1111 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/app_window/app_window.h ('k') | extensions/browser/app_window/app_window_contents.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698