Chromium Code Reviews| Index: chrome/browser/ui/unload_controller.cc |
| diff --git a/chrome/browser/ui/unload_controller.cc b/chrome/browser/ui/unload_controller.cc |
| index 7a30244ff82a5b5d2a596bc747714e12bc18e913..bc426e79d0a521258c8fe7d3a208e3e0ee18ad36 100644 |
| --- a/chrome/browser/ui/unload_controller.cc |
| +++ b/chrome/browser/ui/unload_controller.cc |
| @@ -12,6 +12,7 @@ |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_tabstrip.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| +#include "chrome/browser/ui/unload_controller_web_contents_delegate.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_source.h" |
| #include "content/public/browser/notification_types.h" |
| @@ -120,7 +121,7 @@ bool UnloadController::BeforeUnloadFired(content::WebContents* contents, |
| // Now that beforeunload has fired, put the tab on the queue to fire |
| // unload. |
| tabs_needing_unload_fired_.insert(contents); |
| - ProcessPendingTabs(); |
| + ProcessPendingTabs(false); |
| // We want to handle firing the unload event ourselves since we want to |
| // fire all the beforeunload events before attempting to fire the unload |
| // events should the user cancel closing the browser. |
| @@ -163,11 +164,12 @@ bool UnloadController::ShouldCloseWindow() { |
| // Cases 2 and 3. |
| on_close_confirmed_.Reset(); |
| - ProcessPendingTabs(); |
| + ProcessPendingTabs(false); |
| return false; |
| } |
| -bool UnloadController::CallBeforeUnloadHandlers( |
| +bool UnloadController::TryToCloseWindow( |
| + bool skip_beforeunload, |
| const base::Callback<void(bool)>& on_close_confirmed) { |
| // The devtools browser gets its beforeunload events as the results of |
| // intercepting events from the inspected tab, so don't send them here as |
| @@ -179,11 +181,11 @@ bool UnloadController::CallBeforeUnloadHandlers( |
| is_attempting_to_close_browser_ = true; |
| on_close_confirmed_ = on_close_confirmed; |
| - ProcessPendingTabs(); |
| - return true; |
| + ProcessPendingTabs(skip_beforeunload); |
| + return true && !skip_beforeunload; |
|
sky
2017/03/14 00:04:05
return !skip_beforeunload
zmin
2017/03/14 17:46:47
Done.
|
| } |
| -void UnloadController::ResetBeforeUnloadHandlers() { |
| +void UnloadController::ResetTryToCloseWindow() { |
| if (!is_calling_before_unload_handlers()) |
| return; |
| CancelWindowClose(); |
| @@ -290,7 +292,7 @@ void UnloadController::TabDetachedImpl(content::WebContents* contents) { |
| content::Source<content::WebContents>(contents)); |
| } |
| -void UnloadController::ProcessPendingTabs() { |
| +void UnloadController::ProcessPendingTabs(bool skip_beforeunload) { |
| // Cancel posted/queued ProcessPendingTabs task if there is any. |
| weak_factory_.InvalidateWeakPtrs(); |
| @@ -308,6 +310,18 @@ void UnloadController::ProcessPendingTabs() { |
| return; |
| } |
| + if (skip_beforeunload) { |
| + tabs_needing_unload_fired_.insert(tabs_needing_before_unload_fired_.begin(), |
| + tabs_needing_before_unload_fired_.end()); |
| + if (!web_contents_delegate_) |
| + web_contents_delegate_.reset(new UnloadControllerWebContentsDelegate()); |
|
sky
2017/03/14 00:04:05
MakeUnique
zmin
2017/03/14 17:46:47
Done.
|
| + for (UnloadListenerSet::iterator it = tabs_needing_unload_fired_.begin(); |
| + it != tabs_needing_unload_fired_.end(); ++it) { |
| + (*it)->SetDelegate(web_contents_delegate_.get()); |
|
sky
2017/03/14 00:04:05
How do you know it's safe to reset the delegate? M
zmin
2017/03/14 17:46:47
This delegate makes sure that after windows are cl
sky
2017/03/14 20:26:34
AFAIK FastUnloadController isn't shipping yet, so
Charlie Reis
2017/03/14 23:21:44
That's a great question. It looks like it depends
|
| + } |
| + tabs_needing_before_unload_fired_.clear(); |
| + } |
| + |
| // Process beforeunload tabs first. When that queue is empty, process |
| // unload tabs. |
| if (!tabs_needing_before_unload_fired_.empty()) { |
| @@ -332,7 +346,8 @@ void UnloadController::ProcessPendingTabs() { |
| // is complete. |
| if (tabs_needing_unload_fired_.empty()) |
| on_close_confirmed_.Reset(); |
| - on_close_confirmed.Run(true); |
| + if (!skip_beforeunload) |
| + on_close_confirmed.Run(true); |
| } else if (!tabs_needing_unload_fired_.empty()) { |
| // We've finished firing all beforeunload events and can proceed with unload |
| // events. |
| @@ -380,14 +395,15 @@ void UnloadController::ClearUnloadState(content::WebContents* web_contents, |
| RemoveFromSet(&tabs_needing_before_unload_fired_, web_contents); |
| RemoveFromSet(&tabs_needing_unload_fired_, web_contents); |
| if (process_now) { |
| - ProcessPendingTabs(); |
| + ProcessPendingTabs(false); |
| } else { |
| // Do not post a new task if there is already any. |
| if (weak_factory_.HasWeakPtrs()) |
| return; |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, base::Bind(&UnloadController::ProcessPendingTabs, |
| - weak_factory_.GetWeakPtr())); |
| + FROM_HERE, |
| + base::Bind(&UnloadController::ProcessPendingTabs, |
| + weak_factory_.GetWeakPtr(), false)); |
| } |
| } |
| } |