add-flag-for-close-confirmation.patch 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. --- a/chrome/browser/ui/browser.cc
  2. +++ b/chrome/browser/ui/browser.cc
  3. @@ -138,6 +138,8 @@
  4. #include "chrome/browser/ui/tabs/tab_strip_model.h"
  5. #include "chrome/browser/ui/tabs/tab_utils.h"
  6. #include "chrome/browser/ui/ui_features.h"
  7. +#include "chrome/browser/ui/views/frame/browser_view.h"
  8. +#include "chrome/browser/ui/views/message_box_dialog.h"
  9. #include "chrome/browser/ui/web_applications/app_browser_controller.h"
  10. #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
  11. #include "chrome/browser/ui/webui/signin/login_ui_service.h"
  12. @@ -474,6 +476,7 @@ Browser::Browser(const CreateParams& par
  13. omit_from_session_restore_(params.omit_from_session_restore),
  14. should_trigger_session_restore_(params.should_trigger_session_restore),
  15. cancel_download_confirmation_state_(NOT_PROMPTED),
  16. + close_multitab_confirmation_state_(NOT_PROMPTED),
  17. override_bounds_(params.initial_bounds),
  18. initial_show_state_(params.initial_show_state),
  19. initial_workspace_(params.initial_workspace),
  20. @@ -836,7 +839,7 @@ Browser::WarnBeforeClosingResult Browser
  21. // If the browser can close right away (there are no pending downloads we need
  22. // to prompt about) then there's no need to warn. In the future, we might need
  23. // to check other conditions as well.
  24. - if (CanCloseWithInProgressDownloads())
  25. + if (CanCloseWithInProgressDownloads() && CanCloseWithMultipleTabs())
  26. return WarnBeforeClosingResult::kOkToClose;
  27. DCHECK(!warn_before_closing_callback_)
  28. @@ -866,6 +869,7 @@ bool Browser::TryToCloseWindow(
  29. void Browser::ResetTryToCloseWindow() {
  30. cancel_download_confirmation_state_ = NOT_PROMPTED;
  31. + close_multitab_confirmation_state_ = NOT_PROMPTED;
  32. unload_controller_.ResetTryToCloseWindow();
  33. }
  34. @@ -2732,6 +2736,62 @@ bool Browser::CanCloseWithInProgressDown
  35. return false;
  36. }
  37. +bool Browser::CanCloseWithMultipleTabs() {
  38. + if (!base::CommandLine::ForCurrentProcess()->HasSwitch("close-confirmation"))
  39. + return true;
  40. +
  41. + // If we've prompted, we need to hear from the user before we
  42. + // can close.
  43. + if (close_multitab_confirmation_state_ != NOT_PROMPTED)
  44. + return close_multitab_confirmation_state_ != WAITING_FOR_RESPONSE;
  45. +
  46. + // If we're not running a full browser process with a profile manager
  47. + // (testing), it's ok to close the browser.
  48. + if (!g_browser_process->profile_manager())
  49. + return true;
  50. +
  51. + // Figure out how many windows are open total
  52. + int total_window_count = 0;
  53. + for (auto* browser : *BrowserList::GetInstance()) {
  54. + // Don't count this browser window or any other in the process of closing.
  55. + // Window closing may be delayed, and windows that are in the process of
  56. + // closing don't count against our totals.
  57. + if (browser == this || browser->IsAttemptingToCloseBrowser())
  58. + continue;
  59. + total_window_count++;
  60. + }
  61. +
  62. + const auto flag_value = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("close-confirmation");
  63. + bool show_confirmation_last_window = flag_value == "last";
  64. +
  65. + if (show_confirmation_last_window) {
  66. + if (total_window_count >= 1 || this->tab_strip_model()->count() <= 1)
  67. + return true;
  68. + } else {
  69. + if (total_window_count == 0)
  70. + return true;
  71. + if (this->tab_strip_model()->count() == 0)
  72. + tab_strip_model_delegate_->AddTabAt(GURL(), -1, true);
  73. + }
  74. +
  75. + close_multitab_confirmation_state_ = WAITING_FOR_RESPONSE;
  76. +
  77. + // The dialog eats mouse events which results in the close button
  78. + // getting stuck in the hover state. Reset the window controls to
  79. + // prevent this.
  80. + ((BrowserView*)window_)->frame()->non_client_view()->ResetWindowControls();
  81. + auto callback = base::BindOnce(&Browser::MultitabResponse,
  82. + weak_factory_.GetWeakPtr());
  83. + MessageBoxDialog::Show(window_->GetNativeWindow(),
  84. + u"Do you want to close this window?", std::u16string(),
  85. + chrome::MESSAGE_BOX_TYPE_QUESTION, u"Close", u"Cancel",
  86. + std::u16string(), std::move(callback));
  87. +
  88. + // Return false so the browser does not close. We'll close if the user
  89. + // confirms in the dialog.
  90. + return false;
  91. +}
  92. +
  93. void Browser::InProgressDownloadResponse(bool cancel_downloads) {
  94. if (cancel_downloads) {
  95. cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
  96. @@ -2750,6 +2810,22 @@ void Browser::InProgressDownloadResponse
  97. std::move(warn_before_closing_callback_)
  98. .Run(WarnBeforeClosingResult::kDoNotClose);
  99. +}
  100. +
  101. +void Browser::MultitabResponse(chrome::MessageBoxResult result) {
  102. + if (result == chrome::MESSAGE_BOX_RESULT_YES) {
  103. + close_multitab_confirmation_state_ = RESPONSE_RECEIVED;
  104. + std::move(warn_before_closing_callback_)
  105. + .Run(WarnBeforeClosingResult::kOkToClose);
  106. + return;
  107. + }
  108. +
  109. + // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
  110. + // close again we'll show the warning again.
  111. + close_multitab_confirmation_state_ = NOT_PROMPTED;
  112. +
  113. + std::move(warn_before_closing_callback_)
  114. + .Run(WarnBeforeClosingResult::kDoNotClose);
  115. }
  116. void Browser::FinishWarnBeforeClosing(WarnBeforeClosingResult result) {
  117. --- a/chrome/browser/ui/browser.h
  118. +++ b/chrome/browser/ui/browser.h
  119. @@ -27,6 +27,7 @@
  120. #include "chrome/browser/ui/bookmarks/bookmark_tab_helper_observer.h"
  121. #include "chrome/browser/ui/browser_navigator_params.h"
  122. #include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
  123. +#include "chrome/browser/ui/simple_message_box.h"
  124. #include "chrome/browser/ui/signin_view_controller.h"
  125. #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
  126. #include "chrome/browser/ui/unload_controller.h"
  127. @@ -1030,12 +1031,17 @@ class Browser : public TabStripModelObse
  128. // Returns true if the window can close, false otherwise.
  129. bool CanCloseWithInProgressDownloads();
  130. + // Called when the window is closing to check if more than one tabs are open
  131. + bool CanCloseWithMultipleTabs();
  132. +
  133. // Called when the user has decided whether to proceed or not with the browser
  134. // closure. |cancel_downloads| is true if the downloads should be canceled
  135. // and the browser closed, false if the browser should stay open and the
  136. // downloads running.
  137. void InProgressDownloadResponse(bool cancel_downloads);
  138. + void MultitabResponse(chrome::MessageBoxResult result);
  139. +
  140. // Called when all warnings have completed when attempting to close the
  141. // browser directly (e.g. via hotkey, close button, terminate signal, etc.)
  142. // Used as a WarnBeforeClosingCallback by ShouldCloseWindow().
  143. @@ -1202,6 +1208,8 @@ class Browser : public TabStripModelObse
  144. // when the browser is closed with in-progress downloads.
  145. CancelDownloadConfirmationState cancel_download_confirmation_state_;
  146. + CancelDownloadConfirmationState close_multitab_confirmation_state_;
  147. +
  148. /////////////////////////////////////////////////////////////////////////////
  149. // Override values for the bounds of the window and its maximized or minimized
  150. --- a/chrome/browser/ungoogled_flag_choices.h
  151. +++ b/chrome/browser/ungoogled_flag_choices.h
  152. @@ -61,4 +61,13 @@ const FeatureEntry::Choice kCloseWindowW
  153. "close-window-with-last-tab",
  154. "never"},
  155. };
  156. +const FeatureEntry::Choice kCloseConfirmation[] = {
  157. + {flags_ui::kGenericExperimentChoiceDefault, "", ""},
  158. + {"Show confirmation with last window",
  159. + "close-confirmation",
  160. + "last"},
  161. + {"Show confirmation with multiple windows",
  162. + "close-confirmation",
  163. + "multiple"},
  164. +};
  165. #endif // CHROME_BROWSER_UNGOOGLED_FLAG_CHOICES_H_
  166. --- a/chrome/browser/ungoogled_flag_entries.h
  167. +++ b/chrome/browser/ungoogled_flag_entries.h
  168. @@ -72,4 +72,8 @@
  169. "Remove Grab Handle",
  170. "Removes the reserved empty space in the tabstrip for moving the window. ungoogled-chromium flag",
  171. kOsDesktop, SINGLE_VALUE_TYPE("remove-grab-handle")},
  172. + {"close-confirmation",
  173. + "Close Confirmation",
  174. + "Show a warning prompt when closing the browser window. ungoogled-chromium flag",
  175. + kOsDesktop, MULTI_VALUE_TYPE(kCloseConfirmation)},
  176. #endif // CHROME_BROWSER_UNGOOGLED_FLAG_ENTRIES_H_