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

Unified Diff: chrome/browser/ui/unload_controller.h

Issue 11016023: Quickly close tabs/window with long-running unload handlers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Keep original TabsNeedBeforeUnloadFired implementation. Created 8 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/unload_controller.h
diff --git a/chrome/browser/ui/unload_controller.h b/chrome/browser/ui/unload_controller.h
index 512217a96b5e3aadd01c7340b86ddfb97c7d88d0..a2ba5aaedf7a75e6a983f296bf28ec3ee9c41017 100644
--- a/chrome/browser/ui/unload_controller.h
+++ b/chrome/browser/ui/unload_controller.h
@@ -7,6 +7,7 @@
#include <set>
+#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "content/public/browser/notification_observer.h"
@@ -23,7 +24,36 @@ class WebContents;
}
namespace chrome {
-
+class UnloadDetachedHandler;
+
+// UnloadController manages closing tabs and windows -- especially in
+// regards to beforeunload handlers (proceed/cancel dialogs) and
+// unload handlers (no user interaction).
+//
+// Typical flow of closing a tab:
+// 1. Browser calls |CanCloseContents()|.
+// If true, browser calls contents::CloseWebContents().
+// 2. WebContents notifies us via its delegate and BeforeUnloadFired()
+// that the beforeunload handler was run. If the user allowed the
+// close to continue, we hand-off running the unload handler to
+// UnloadDetachedHandler. The tab is removed from the tab strip at
+// this point.
+//
+// Typical flow of closing a window:
+// 1. BrowserView::CanClose() calls TabsNeedBeforeUnloadFired().
+// If beforeunload/unload handlers need to run, UnloadController returns
+// true and calls ProcessPendingTabs() (private method).
+// 2. For each tab with a beforeunload/unload handler, ProcessPendingTabs()
+// calls |web_contents->OnCloseStarted()|
+// and |web_contents->GetRenderViewHost()->FirePageBeforeUnload()|.
+// 3. If the user allowed the close to continue, we hand-off all the tabs with
+// unload handlers to UnloadDetachedHandler. All the tabs are removed
+// from the tab strip.
+// 4. The browser gets notified that the tab strip is empty and calls
+// CloseFrame where the empty tab strip causes the window to hide.
+// Once the detached tabs finish, the browser calls CloseFrame again and
+// the window is finally closed.
+//
class UnloadController : public content::NotificationObserver,
public TabStripModelObserver {
public:
@@ -115,11 +145,11 @@ class UnloadController : public content::NotificationObserver,
content::NotificationRegistrar registrar_;
- // Tracks tabs that need there beforeunload event fired before we can
+ // Tracks tabs that need their beforeunload event fired before we can
// close the browser. Only gets populated when we try to close the browser.
UnloadListenerSet tabs_needing_before_unload_fired_;
- // Tracks tabs that need there unload event fired before we can
+ // Tracks tabs that need their unload event fired before we can
// close the browser. Only gets populated when we try to close the browser.
UnloadListenerSet tabs_needing_unload_fired_;
@@ -129,6 +159,9 @@ class UnloadController : public content::NotificationObserver,
// Browser window isn't just immediately closed.
bool is_attempting_to_close_browser_;
+ // Allow unload handlers to run without holding up the UI.
+ scoped_ptr<UnloadDetachedHandler> unload_detached_handler_;
+
base::WeakPtrFactory<UnloadController> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(UnloadController);

Powered by Google App Engine
This is Rietveld 408576698