123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- --- a/chrome/browser/ui/browser.cc
- +++ b/chrome/browser/ui/browser.cc
- @@ -138,6 +138,8 @@
- #include "chrome/browser/ui/tabs/tab_strip_model.h"
- #include "chrome/browser/ui/tabs/tab_utils.h"
- #include "chrome/browser/ui/ui_features.h"
- +#include "chrome/browser/ui/views/frame/browser_view.h"
- +#include "chrome/browser/ui/views/message_box_dialog.h"
- #include "chrome/browser/ui/web_applications/app_browser_controller.h"
- #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
- #include "chrome/browser/ui/webui/signin/login_ui_service.h"
- @@ -474,6 +476,7 @@ Browser::Browser(const CreateParams& par
- omit_from_session_restore_(params.omit_from_session_restore),
- should_trigger_session_restore_(params.should_trigger_session_restore),
- cancel_download_confirmation_state_(NOT_PROMPTED),
- + close_multitab_confirmation_state_(NOT_PROMPTED),
- override_bounds_(params.initial_bounds),
- initial_show_state_(params.initial_show_state),
- initial_workspace_(params.initial_workspace),
- @@ -836,7 +839,7 @@ Browser::WarnBeforeClosingResult Browser
- // If the browser can close right away (there are no pending downloads we need
- // to prompt about) then there's no need to warn. In the future, we might need
- // to check other conditions as well.
- - if (CanCloseWithInProgressDownloads())
- + if (CanCloseWithInProgressDownloads() && CanCloseWithMultipleTabs())
- return WarnBeforeClosingResult::kOkToClose;
-
- DCHECK(!warn_before_closing_callback_)
- @@ -866,6 +869,7 @@ bool Browser::TryToCloseWindow(
-
- void Browser::ResetTryToCloseWindow() {
- cancel_download_confirmation_state_ = NOT_PROMPTED;
- + close_multitab_confirmation_state_ = NOT_PROMPTED;
- unload_controller_.ResetTryToCloseWindow();
- }
-
- @@ -2732,6 +2736,62 @@ bool Browser::CanCloseWithInProgressDown
- return false;
- }
-
- +bool Browser::CanCloseWithMultipleTabs() {
- + if (!base::CommandLine::ForCurrentProcess()->HasSwitch("close-confirmation"))
- + return true;
- +
- + // If we've prompted, we need to hear from the user before we
- + // can close.
- + if (close_multitab_confirmation_state_ != NOT_PROMPTED)
- + return close_multitab_confirmation_state_ != WAITING_FOR_RESPONSE;
- +
- + // If we're not running a full browser process with a profile manager
- + // (testing), it's ok to close the browser.
- + if (!g_browser_process->profile_manager())
- + return true;
- +
- + // Figure out how many windows are open total
- + int total_window_count = 0;
- + for (auto* browser : *BrowserList::GetInstance()) {
- + // Don't count this browser window or any other in the process of closing.
- + // Window closing may be delayed, and windows that are in the process of
- + // closing don't count against our totals.
- + if (browser == this || browser->IsAttemptingToCloseBrowser())
- + continue;
- + total_window_count++;
- + }
- +
- + const auto flag_value = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("close-confirmation");
- + bool show_confirmation_last_window = flag_value == "last";
- +
- + if (show_confirmation_last_window) {
- + if (total_window_count >= 1 || this->tab_strip_model()->count() <= 1)
- + return true;
- + } else {
- + if (total_window_count == 0)
- + return true;
- + if (this->tab_strip_model()->count() == 0)
- + tab_strip_model_delegate_->AddTabAt(GURL(), -1, true);
- + }
- +
- + close_multitab_confirmation_state_ = WAITING_FOR_RESPONSE;
- +
- + // The dialog eats mouse events which results in the close button
- + // getting stuck in the hover state. Reset the window controls to
- + // prevent this.
- + ((BrowserView*)window_)->frame()->non_client_view()->ResetWindowControls();
- + auto callback = base::BindOnce(&Browser::MultitabResponse,
- + weak_factory_.GetWeakPtr());
- + MessageBoxDialog::Show(window_->GetNativeWindow(),
- + u"Do you want to close this window?", std::u16string(),
- + chrome::MESSAGE_BOX_TYPE_QUESTION, u"Close", u"Cancel",
- + std::u16string(), std::move(callback));
- +
- + // Return false so the browser does not close. We'll close if the user
- + // confirms in the dialog.
- + return false;
- +}
- +
- void Browser::InProgressDownloadResponse(bool cancel_downloads) {
- if (cancel_downloads) {
- cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
- @@ -2750,6 +2810,22 @@ void Browser::InProgressDownloadResponse
-
- std::move(warn_before_closing_callback_)
- .Run(WarnBeforeClosingResult::kDoNotClose);
- +}
- +
- +void Browser::MultitabResponse(chrome::MessageBoxResult result) {
- + if (result == chrome::MESSAGE_BOX_RESULT_YES) {
- + close_multitab_confirmation_state_ = RESPONSE_RECEIVED;
- + std::move(warn_before_closing_callback_)
- + .Run(WarnBeforeClosingResult::kOkToClose);
- + return;
- + }
- +
- + // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
- + // close again we'll show the warning again.
- + close_multitab_confirmation_state_ = NOT_PROMPTED;
- +
- + std::move(warn_before_closing_callback_)
- + .Run(WarnBeforeClosingResult::kDoNotClose);
- }
-
- void Browser::FinishWarnBeforeClosing(WarnBeforeClosingResult result) {
- --- a/chrome/browser/ui/browser.h
- +++ b/chrome/browser/ui/browser.h
- @@ -27,6 +27,7 @@
- #include "chrome/browser/ui/bookmarks/bookmark_tab_helper_observer.h"
- #include "chrome/browser/ui/browser_navigator_params.h"
- #include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
- +#include "chrome/browser/ui/simple_message_box.h"
- #include "chrome/browser/ui/signin_view_controller.h"
- #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
- #include "chrome/browser/ui/unload_controller.h"
- @@ -1030,12 +1031,17 @@ class Browser : public TabStripModelObse
- // Returns true if the window can close, false otherwise.
- bool CanCloseWithInProgressDownloads();
-
- + // Called when the window is closing to check if more than one tabs are open
- + bool CanCloseWithMultipleTabs();
- +
- // Called when the user has decided whether to proceed or not with the browser
- // closure. |cancel_downloads| is true if the downloads should be canceled
- // and the browser closed, false if the browser should stay open and the
- // downloads running.
- void InProgressDownloadResponse(bool cancel_downloads);
-
- + void MultitabResponse(chrome::MessageBoxResult result);
- +
- // Called when all warnings have completed when attempting to close the
- // browser directly (e.g. via hotkey, close button, terminate signal, etc.)
- // Used as a WarnBeforeClosingCallback by ShouldCloseWindow().
- @@ -1202,6 +1208,8 @@ class Browser : public TabStripModelObse
- // when the browser is closed with in-progress downloads.
- CancelDownloadConfirmationState cancel_download_confirmation_state_;
-
- + CancelDownloadConfirmationState close_multitab_confirmation_state_;
- +
- /////////////////////////////////////////////////////////////////////////////
-
- // Override values for the bounds of the window and its maximized or minimized
- --- a/chrome/browser/ungoogled_flag_choices.h
- +++ b/chrome/browser/ungoogled_flag_choices.h
- @@ -61,4 +61,13 @@ const FeatureEntry::Choice kCloseWindowW
- "close-window-with-last-tab",
- "never"},
- };
- +const FeatureEntry::Choice kCloseConfirmation[] = {
- + {flags_ui::kGenericExperimentChoiceDefault, "", ""},
- + {"Show confirmation with last window",
- + "close-confirmation",
- + "last"},
- + {"Show confirmation with multiple windows",
- + "close-confirmation",
- + "multiple"},
- +};
- #endif // CHROME_BROWSER_UNGOOGLED_FLAG_CHOICES_H_
- --- a/chrome/browser/ungoogled_flag_entries.h
- +++ b/chrome/browser/ungoogled_flag_entries.h
- @@ -72,4 +72,8 @@
- "Remove Grab Handle",
- "Removes the reserved empty space in the tabstrip for moving the window. ungoogled-chromium flag",
- kOsDesktop, SINGLE_VALUE_TYPE("remove-grab-handle")},
- + {"close-confirmation",
- + "Close Confirmation",
- + "Show a warning prompt when closing the browser window. ungoogled-chromium flag",
- + kOsDesktop, MULTI_VALUE_TYPE(kCloseConfirmation)},
- #endif // CHROME_BROWSER_UNGOOGLED_FLAG_ENTRIES_H_
|