| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/browser_command_controller.h" |
| |
| #include <stddef.h> |
| |
| #include <string> |
| |
| #include "base/command_line.h" |
| #include "base/containers/contains.h" |
| #include "base/debug/debugging_buildflags.h" |
| #include "base/debug/profiler.h" |
| #include "base/feature_list.h" |
| #include "base/functional/bind.h" |
| #include "base/i18n/rtl.h" |
| #include "base/metrics/histogram_functions.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/time/time.h" |
| #include "build/branding_buildflags.h" |
| #include "build/build_config.h" |
| #include "chrome/app/chrome_command_ids.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/commerce/browser_utils.h" |
| #include "chrome/browser/defaults.h" |
| #include "chrome/browser/devtools/devtools_window.h" |
| #include "chrome/browser/feedback/public/feedback_source.h" |
| #include "chrome/browser/lifetime/application_lifetime.h" |
| #include "chrome/browser/prefs/incognito_mode_prefs.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/profiles/profile_window.h" |
| #include "chrome/browser/sessions/tab_restore_service_factory.h" |
| #include "chrome/browser/sharing_hub/sharing_hub_features.h" |
| #include "chrome/browser/shell_integration.h" |
| #include "chrome/browser/signin/identity_manager_factory.h" |
| #include "chrome/browser/signin/signin_promo.h" |
| #include "chrome/browser/signin/signin_ui_util.h" |
| #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_actions.h" |
| #include "chrome/browser/ui/browser_commands.h" |
| #include "chrome/browser/ui/browser_dialogs.h" |
| #include "chrome/browser/ui/browser_finder.h" |
| #include "chrome/browser/ui/browser_list.h" |
| #include "chrome/browser/ui/browser_navigator.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/browser/ui/browser_window/public/browser_window_features.h" |
| #include "chrome/browser/ui/bubble_anchor_util.h" |
| #include "chrome/browser/ui/chrome_pages.h" |
| #include "chrome/browser/ui/customize_chrome/side_panel_controller.h" |
| #include "chrome/browser/ui/lens/lens_overlay_controller.h" |
| #include "chrome/browser/ui/managed_ui.h" |
| #include "chrome/browser/ui/page_info/page_info_dialog.h" |
| #include "chrome/browser/ui/passwords/ui_utils.h" |
| #include "chrome/browser/ui/profiles/profile_picker.h" |
| #include "chrome/browser/ui/profiles/profile_view_utils.h" |
| #include "chrome/browser/ui/singleton_tabs.h" |
| #include "chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.h" |
| #include "chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_prefs.h" |
| #include "chrome/browser/ui/tabs/features.h" |
| #include "chrome/browser/ui/tabs/public/tab_features.h" |
| #include "chrome/browser/ui/tabs/tab_model.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/browser/ui/tabs/tab_strip_user_gesture_details.h" |
| #include "chrome/browser/ui/toolbar/chrome_labs/chrome_labs_utils.h" |
| #include "chrome/browser/ui/ui_features.h" |
| #include "chrome/browser/ui/views/side_panel/side_panel_entry_id.h" |
| #include "chrome/browser/ui/views/side_panel/side_panel_enums.h" |
| #include "chrome/browser/ui/views/side_panel/side_panel_ui.h" |
| #include "chrome/browser/ui/web_applications/app_browser_controller.h" |
| #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h" |
| #include "chrome/browser/ui/web_applications/web_app_launch_utils.h" |
| #include "chrome/browser/ui/web_applications/web_app_tabbed_utils.h" |
| #include "chrome/browser/ui/webui/inspect/inspect_ui.h" |
| #include "chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_section.h" |
| #include "chrome/browser/web_applications/web_app_install_params.h" |
| #include "chrome/browser/web_applications/web_app_utils.h" |
| #include "chrome/common/chrome_features.h" |
| #include "chrome/common/content_restriction.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/common/webui_url_constants.h" |
| #include "components/bookmarks/common/bookmark_pref_names.h" |
| #include "components/dom_distiller/core/dom_distiller_features.h" |
| #include "components/input/native_web_keyboard_event.h" |
| #include "components/lens/buildflags.h" |
| #include "components/password_manager/core/browser/manage_passwords_referrer.h" |
| #include "components/policy/core/common/policy_pref_names.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/sessions/content/session_tab_helper.h" |
| #include "components/sessions/core/tab_restore_service.h" |
| #include "components/signin/public/base/signin_buildflags.h" |
| #include "components/signin/public/base/signin_metrics.h" |
| #include "components/signin/public/base/signin_pref_names.h" |
| #include "components/signin/public/identity_manager/identity_manager.h" |
| #include "components/translate/core/browser/translate_manager.h" |
| #include "content/public/browser/navigation_controller.h" |
| #include "content/public/browser/navigation_entry.h" |
| #include "content/public/browser/render_frame_host.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_contents_observer.h" |
| #include "content/public/common/profiling.h" |
| #include "content/public/common/url_constants.h" |
| #include "extensions/browser/extension_registrar.h" |
| #include "extensions/common/extension_urls.h" |
| #include "printing/buildflags/buildflags.h" |
| #include "ui/actions/actions.h" |
| #include "ui/base/ui_base_features.h" |
| #include "ui/base/window_open_disposition.h" |
| #include "ui/events/keycodes/keyboard_codes.h" |
| |
| #if BUILDFLAG(IS_MAC) |
| #include "chrome/browser/ui/browser_commands_mac.h" |
| #endif |
| |
| #if BUILDFLAG(IS_WIN) |
| #include "base/win/windows_version.h" |
| #include "content/public/browser/gpu_data_manager.h" |
| #endif |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| #include "chrome/browser/platform_util.h" |
| #include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h" |
| #include "chrome/browser/ui/browser_commands_chromeos.h" |
| #include "components/session_manager/core/session_manager.h" |
| #include "components/user_manager/user_manager.h" |
| #endif |
| |
| #if BUILDFLAG(IS_LINUX) |
| #include "ui/base/ime/text_edit_commands.h" |
| #include "ui/base/ime/text_input_flags.h" |
| #include "ui/linux/linux_ui.h" |
| #endif |
| |
| #if BUILDFLAG(IS_OZONE) |
| #include "ui/ozone/public/ozone_platform.h" |
| #endif |
| |
| #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) |
| #include "chrome/browser/ui/shortcuts/desktop_shortcuts_utils.h" |
| #endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) |
| |
| #if BUILDFLAG(ENABLE_GLIC) |
| #include "chrome/browser/glic/glic_enabling.h" |
| #include "chrome/browser/glic/glic_enums.h" |
| #include "chrome/browser/glic/glic_keyed_service_factory.h" |
| #include "chrome/browser/glic/glic_pref_names.h" |
| #include "chrome/browser/glic/glic_profile_manager.h" |
| #endif |
| |
| using WebExposedIsolationLevel = content::WebExposedIsolationLevel; |
| |
| namespace chrome { |
| |
| namespace { |
| |
| // Ensures that - if we have not popped up an infobar to prompt the user to e.g. |
| // reload the current page - that the content pane of the browser is refocused. |
| void AppInfoDialogClosedCallback(SessionID session_id, |
| views::Widget::ClosedReason closed_reason, |
| bool reload_prompt) { |
| if (reload_prompt) { |
| return; |
| } |
| |
| // If the user clicked on something specific or focus was changed, don't |
| // override the focus. |
| if (closed_reason != views::Widget::ClosedReason::kEscKeyPressed && |
| closed_reason != views::Widget::ClosedReason::kCloseButtonClicked) { |
| return; |
| } |
| |
| // Ensure that the session id we have is still valid. It's possible |
| // (though unlikely) that either the browser or session has been pulled |
| // out from underneath us. |
| Browser* const browser = chrome::FindBrowserWithID(session_id); |
| if (!browser) { |
| return; |
| } |
| |
| // We want to focus the active web contents, which again, might not be the |
| // original web contents (though it should be the vast majority of the time). |
| content::WebContents* const active_contents = |
| browser->tab_strip_model()->GetActiveWebContents(); |
| if (active_contents) { |
| active_contents->Focus(); |
| } |
| } |
| |
| bool CanOpenFile(Browser* browser) { |
| if (browser->is_type_devtools() || browser->is_type_app() || |
| browser->is_type_app_popup()) { |
| return false; |
| } |
| |
| PrefService* local_state = g_browser_process->local_state(); |
| // May be null in unit tests. |
| if (local_state) { |
| return local_state->GetBoolean(prefs::kAllowFileSelectionDialogs); |
| } |
| |
| return true; |
| } |
| |
| void InvokeAction(actions::ActionId id, actions::ActionItem* scope) { |
| actions::ActionManager::Get().FindAction(id, scope)->InvokeAction(); |
| } |
| |
| } // namespace |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // BrowserCommandController, public: |
| |
| BrowserCommandController::BrowserCommandController(Browser* browser) |
| : browser_(browser), command_updater_(nullptr) { |
| browser_->tab_strip_model()->AddObserver(this); |
| PrefService* local_state = g_browser_process->local_state(); |
| if (local_state) { |
| local_pref_registrar_.Init(local_state); |
| local_pref_registrar_.Add( |
| prefs::kAllowFileSelectionDialogs, |
| base::BindRepeating( |
| &BrowserCommandController::UpdateCommandsForFileSelectionDialogs, |
| base::Unretained(this))); |
| } |
| |
| profile_pref_registrar_.Init(profile()->GetPrefs()); |
| profile_pref_registrar_.Add( |
| prefs::kDevToolsAvailability, |
| base::BindRepeating(&BrowserCommandController::UpdateCommandsForDevTools, |
| base::Unretained(this))); |
| profile_pref_registrar_.Add( |
| bookmarks::prefs::kEditBookmarksEnabled, |
| base::BindRepeating( |
| &BrowserCommandController::UpdateCommandsForBookmarkEditing, |
| base::Unretained(this))); |
| profile_pref_registrar_.Add( |
| bookmarks::prefs::kShowBookmarkBar, |
| base::BindRepeating( |
| &BrowserCommandController::UpdateCommandsForBookmarkBar, |
| base::Unretained(this))); |
| profile_pref_registrar_.Add( |
| policy::policy_prefs::kIncognitoModeAvailability, |
| base::BindRepeating( |
| &BrowserCommandController::UpdateCommandsForIncognitoAvailability, |
| base::Unretained(this))); |
| #if BUILDFLAG(ENABLE_PRINTING) |
| profile_pref_registrar_.Add( |
| prefs::kPrintingEnabled, |
| base::BindRepeating(&BrowserCommandController::UpdatePrintingState, |
| base::Unretained(this))); |
| #endif // BUILDFLAG(ENABLE_PRINTING) |
| profile_pref_registrar_.Add( |
| policy::policy_prefs::kDownloadRestrictions, |
| base::BindRepeating(&BrowserCommandController::UpdateSaveAsState, |
| base::Unretained(this))); |
| #if !BUILDFLAG(IS_MAC) |
| profile_pref_registrar_.Add( |
| prefs::kFullscreenAllowed, |
| base::BindRepeating( |
| &BrowserCommandController::UpdateCommandsForFullscreenMode, |
| base::Unretained(this))); |
| #endif //! BUILDFLAG(IS_MAC) |
| |
| #if BUILDFLAG(ENABLE_GLIC) |
| if (glic::GlicEnabling::IsEnabledByFlags()) { |
| auto* glic_service = |
| glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile()); |
| if (glic_service) { |
| glic_enabling_subscription_ = std::make_unique< |
| base::CallbackListSubscription>( |
| |
| glic_service->enabling().RegisterAllowedChanged(base::BindRepeating( |
| &BrowserCommandController::UpdateCommandsForEnableGlicChanged, |
| base::Unretained(this)))); |
| } |
| } |
| #endif // BUILDFLAG(ENABLE_GLIC) |
| |
| #if BUILDFLAG(ENABLE_GLIC) |
| if (glic::GlicEnabling::IsEnabledByFlags()) { |
| auto* service = |
| glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile()); |
| if (service) { |
| glic_window_activation_subscription_ = |
| service->window_controller().AddWindowActivationChangedCallback( |
| base::BindRepeating( |
| &BrowserCommandController::GlicWindowActivationChanged, |
| base::Unretained(this))); |
| } |
| } |
| #endif |
| |
| InitCommandState(); |
| |
| sessions::TabRestoreService* tab_restore_service = |
| TabRestoreServiceFactory::GetForProfile(profile()); |
| if (tab_restore_service) { |
| tab_restore_service->AddObserver(this); |
| if (!tab_restore_service->IsLoaded()) { |
| tab_restore_service->LoadTabsFromLastSession(); |
| } |
| } |
| } |
| |
| BrowserCommandController::~BrowserCommandController() { |
| // TabRestoreService may have been shutdown by the time we get here. Don't |
| // trigger creating it. |
| sessions::TabRestoreService* tab_restore_service = |
| TabRestoreServiceFactory::GetForProfileIfExisting(profile()); |
| if (tab_restore_service) { |
| tab_restore_service->RemoveObserver(this); |
| } |
| profile_pref_registrar_.RemoveAll(); |
| local_pref_registrar_.RemoveAll(); |
| glic_enabling_subscription_.reset(); |
| browser_->tab_strip_model()->RemoveObserver(this); |
| } |
| |
| bool BrowserCommandController::IsReservedCommandOrKey( |
| int command_id, |
| const input::NativeWebKeyboardEvent& event) { |
| // In Apps mode, no keys are reserved. |
| if (browser_->is_type_app() || browser_->is_type_app_popup()) { |
| return false; |
| } |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| // On Chrome OS, the top row of keys are mapped to browser actions like |
| // back/forward or refresh. We don't want web pages to be able to change the |
| // behavior of these keys. Ash handles F4 and up; this leaves us needing to |
| // reserve browser back/forward and refresh here. |
| ui::KeyboardCode key_code = |
| static_cast<ui::KeyboardCode>(event.windows_key_code); |
| if ((key_code == ui::VKEY_BROWSER_BACK && command_id == IDC_BACK) || |
| (key_code == ui::VKEY_BROWSER_FORWARD && command_id == IDC_FORWARD) || |
| (key_code == ui::VKEY_BROWSER_REFRESH && command_id == IDC_RELOAD)) { |
| return true; |
| } |
| #endif |
| |
| if (window()->IsFullscreen()) { |
| // In fullscreen, all commands except for IDC_FULLSCREEN and IDC_EXIT should |
| // be delivered to the web page. The intent to implement and ship can be |
| // found in http://crbug.com/680809. |
| const bool is_exit_fullscreen = |
| (command_id == IDC_EXIT || command_id == IDC_FULLSCREEN); |
| #if BUILDFLAG(IS_MAC) |
| // This behavior is different on Mac OS, which has a unique user-initiated |
| // full-screen mode. According to the discussion in http://crbug.com/702251, |
| // the commands should be reserved for browser-side handling if the browser |
| // window's toolbar is visible. |
| if (window()->IsToolbarShowing()) { |
| if (command_id == IDC_FULLSCREEN) { |
| return true; |
| } |
| } else { |
| return is_exit_fullscreen; |
| } |
| #else |
| return is_exit_fullscreen; |
| #endif |
| } |
| |
| #if BUILDFLAG(IS_LINUX) |
| // If this key was registered by the user as a content editing hotkey, then |
| // it is not reserved. |
| auto* linux_ui = ui::LinuxUi::instance(); |
| if (linux_ui && event.os_event && |
| linux_ui->GetTextEditCommandForEvent(*event.os_event, |
| ui::TEXT_INPUT_FLAG_NONE) != |
| ui::TextEditCommand::INVALID_COMMAND) { |
| return false; |
| } |
| #endif |
| |
| return command_id == IDC_CLOSE_TAB || command_id == IDC_CLOSE_WINDOW || |
| command_id == IDC_NEW_INCOGNITO_WINDOW || command_id == IDC_NEW_TAB || |
| command_id == IDC_NEW_WINDOW || command_id == IDC_RESTORE_TAB || |
| command_id == IDC_SELECT_NEXT_TAB || |
| command_id == IDC_SELECT_PREVIOUS_TAB || command_id == IDC_EXIT; |
| } |
| |
| void BrowserCommandController::TabStateChanged() { |
| UpdateCommandsForTabState(); |
| UpdateCommandsForWebContentsFocus(); |
| } |
| |
| void BrowserCommandController::ZoomStateChanged() { |
| UpdateCommandsForZoomState(); |
| } |
| |
| void BrowserCommandController::ContentRestrictionsChanged() { |
| UpdateCommandsForContentRestrictionState(); |
| } |
| |
| void BrowserCommandController::FullscreenStateChanged() { |
| UpdateCommandsForFullscreenMode(); |
| } |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| void BrowserCommandController::LockedFullscreenStateChanged() { |
| UpdateCommandsForLockedFullscreenMode(); |
| } |
| #endif |
| |
| void BrowserCommandController::PrintingStateChanged() { |
| UpdatePrintingState(); |
| } |
| |
| void BrowserCommandController::LoadingStateChanged(bool is_loading, |
| bool force) { |
| UpdateReloadStopState(is_loading, force); |
| } |
| |
| #if BUILDFLAG(ENABLE_GLIC) |
| void BrowserCommandController::GlicWindowActivationChanged(bool active) { |
| UpdateGlicState(); |
| } |
| #endif |
| |
| void BrowserCommandController::FindBarVisibilityChanged() { |
| // Block find command updates in locked fullscreen mode unless the instance is |
| // locked for OnTask (only relevant for non-web browser scenarios). |
| // TODO(crbug.com/365146870): Remove once we consolidate locked fullscreen |
| // with OnTask. |
| bool should_block_command_update = is_locked_fullscreen_; |
| #if BUILDFLAG(IS_CHROMEOS) |
| if (browser_->IsLockedForOnTask()) { |
| should_block_command_update = false; |
| } |
| #endif |
| if (should_block_command_update) { |
| return; |
| } |
| UpdateCloseFindOrStop(); |
| } |
| |
| void BrowserCommandController::ExtensionStateChanged() { |
| // Extensions may disable the bookmark editing commands. |
| UpdateCommandsForBookmarkEditing(); |
| } |
| |
| void BrowserCommandController::TabKeyboardFocusChangedTo( |
| std::optional<int> index) { |
| UpdateCommandsForTabKeyboardFocus(index); |
| } |
| |
| void BrowserCommandController::WebContentsFocusChanged() { |
| UpdateCommandsForWebContentsFocus(); |
| } |
| |
| void BrowserCommandController::ShowCustomizeChromeSidePanel( |
| std::optional<CustomizeChromeSection> section) { |
| tabs::TabInterface* tab = browser_->tab_strip_model()->GetActiveTab(); |
| if (!tab || !tab->GetTabFeatures() || |
| !tab->GetTabFeatures()->customize_chrome_side_panel_controller()) { |
| return; |
| } |
| |
| customize_chrome::SidePanelController* side_panel_controller = |
| tab->GetTabFeatures()->customize_chrome_side_panel_controller(); |
| |
| if (!side_panel_controller || |
| !side_panel_controller->IsCustomizeChromeEntryAvailable()) { |
| return; |
| } |
| |
| side_panel_controller->OpenSidePanel(SidePanelOpenTrigger::kAppMenu, section); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // BrowserCommandController, CommandUpdater implementation: |
| |
| bool BrowserCommandController::SupportsCommand(int id) const { |
| return command_updater_.SupportsCommand(id); |
| } |
| |
| bool BrowserCommandController::IsCommandEnabled(int id) const { |
| return command_updater_.IsCommandEnabled(id); |
| } |
| |
| bool BrowserCommandController::ExecuteCommand(int id, |
| base::TimeTicks time_stamp) { |
| return ExecuteCommandWithDisposition(id, WindowOpenDisposition::CURRENT_TAB, |
| time_stamp); |
| } |
| |
| bool BrowserCommandController::ExecuteCommandWithDisposition( |
| int id, |
| WindowOpenDisposition disposition, |
| base::TimeTicks time_stamp) { |
| // Doesn't go through the command_updater_ to avoid dealing with having a |
| // naming collision for ExecuteCommandWithDisposition (both |
| // CommandUpdaterDelegate and CommandUpdater declare this function so we |
| // choose to not implement CommandUpdaterDelegate inside this class and |
| // therefore command_updater_ doesn't have the delegate set). |
| if (!SupportsCommand(id) || !IsCommandEnabled(id)) { |
| return false; |
| } |
| |
| // No commands are enabled if there is not yet any selected tab. |
| // TODO(pkasting): It seems like we should not need this, because either |
| // most/all commands should not have been enabled yet anyway or the ones that |
| // are enabled should be global, or safe themselves against having no selected |
| // tab. However, Ben says he tried removing this before and got lots of |
| // crashes, e.g. from Windows sending WM_COMMANDs at random times during |
| // window construction. This probably could use closer examination someday. |
| if (browser_->tab_strip_model()->active_index() == TabStripModel::kNoTab) { |
| return true; |
| } |
| |
| DCHECK(command_updater_.IsCommandEnabled(id)) |
| << "Invalid/disabled command " << id; |
| |
| // The order of commands in this switch statement must match the function |
| // declaration order in browser.h! |
| switch (id) { |
| // Navigation commands |
| case IDC_BACK: |
| GoBack(browser_, disposition); |
| break; |
| case IDC_FORWARD: |
| GoForward(browser_, disposition); |
| break; |
| case IDC_RELOAD: |
| Reload(browser_, disposition); |
| break; |
| case IDC_RELOAD_CLEARING_CACHE: |
| ClearCache(browser_); |
| [[fallthrough]]; |
| case IDC_RELOAD_BYPASSING_CACHE: |
| ReloadBypassingCache(browser_, disposition); |
| break; |
| case IDC_HOME: |
| Home(browser_, disposition); |
| break; |
| case IDC_OPEN_CURRENT_URL: |
| OpenCurrentURL(browser_); |
| break; |
| case IDC_STOP: |
| Stop(browser_); |
| break; |
| case IDC_TAB_SEARCH: |
| ShowTabSearch(browser_); |
| break; |
| case IDC_TAB_SEARCH_CLOSE: |
| CloseTabSearch(browser_); |
| break; |
| |
| // Window management commands |
| case IDC_NEW_WINDOW: |
| NewWindow(browser_); |
| break; |
| case IDC_NEW_INCOGNITO_WINDOW: |
| NewIncognitoWindow(profile()); |
| break; |
| case IDC_CLOSE_WINDOW: |
| base::RecordAction(base::UserMetricsAction("CloseWindowByKey")); |
| CloseWindow(browser_); |
| break; |
| case IDC_NEW_TAB: { |
| NewTab(browser_); |
| break; |
| } |
| case IDC_NEW_TAB_TO_RIGHT: { |
| NewTabToRight(browser_); |
| break; |
| } |
| case IDC_CLOSE_TAB: |
| base::RecordAction(base::UserMetricsAction("CloseTabByKey")); |
| CloseTab(browser_); |
| break; |
| case IDC_SELECT_NEXT_TAB: |
| base::RecordAction(base::UserMetricsAction("Accel_SelectNextTab")); |
| SelectNextTab( |
| browser_, |
| TabStripUserGestureDetails( |
| TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp)); |
| break; |
| case IDC_SELECT_PREVIOUS_TAB: |
| base::RecordAction(base::UserMetricsAction("Accel_SelectPreviousTab")); |
| SelectPreviousTab( |
| browser_, |
| TabStripUserGestureDetails( |
| TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp)); |
| break; |
| case IDC_MOVE_TAB_NEXT: |
| MoveTabNext(browser_); |
| break; |
| case IDC_MOVE_TAB_PREVIOUS: |
| MoveTabPrevious(browser_); |
| break; |
| case IDC_SELECT_TAB_0: |
| case IDC_SELECT_TAB_1: |
| case IDC_SELECT_TAB_2: |
| case IDC_SELECT_TAB_3: |
| case IDC_SELECT_TAB_4: |
| case IDC_SELECT_TAB_5: |
| case IDC_SELECT_TAB_6: |
| case IDC_SELECT_TAB_7: |
| base::RecordAction(base::UserMetricsAction("Accel_SelectNumberedTab")); |
| SelectNumberedTab( |
| browser_, id - IDC_SELECT_TAB_0, |
| TabStripUserGestureDetails( |
| TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp)); |
| break; |
| case IDC_SELECT_LAST_TAB: |
| base::RecordAction(base::UserMetricsAction("Accel_SelectNumberedTab")); |
| SelectLastTab( |
| browser_, |
| TabStripUserGestureDetails( |
| TabStripUserGestureDetails::GestureType::kKeyboard, time_stamp)); |
| break; |
| case IDC_DUPLICATE_TAB: |
| DuplicateTab(browser_); |
| break; |
| case IDC_RESTORE_TAB: |
| RestoreTab(browser_); |
| break; |
| case IDC_SHOW_AS_TAB: |
| ConvertPopupToTabbedBrowser(browser_); |
| break; |
| case IDC_FULLSCREEN: |
| chrome::ToggleFullscreenMode(browser_, /*user_initiated=*/true); |
| break; |
| case IDC_OPEN_IN_PWA_WINDOW: |
| base::RecordAction(base::UserMetricsAction("OpenActiveTabInPwaWindow")); |
| web_app::ReparentWebAppForActiveTab(browser_); |
| break; |
| case IDC_MOVE_TAB_TO_NEW_WINDOW: |
| MoveActiveTabToNewWindow(browser_); |
| break; |
| case IDC_NAME_WINDOW: |
| PromptToNameWindow(browser_); |
| break; |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| case IDC_TAKE_SCREENSHOT: |
| TakeScreenshot(); |
| break; |
| case IDC_TOGGLE_MULTITASK_MENU: |
| ToggleMultitaskMenu(browser_); |
| break; |
| case IDC_VISIT_DESKTOP_OF_LRU_USER_2: |
| case IDC_VISIT_DESKTOP_OF_LRU_USER_3: |
| case IDC_VISIT_DESKTOP_OF_LRU_USER_4: |
| case IDC_VISIT_DESKTOP_OF_LRU_USER_5: |
| ExecuteVisitDesktopCommand(id, window()->GetNativeWindow()); |
| break; |
| #endif |
| |
| #if BUILDFLAG(IS_LINUX) |
| case IDC_MINIMIZE_WINDOW: |
| browser_->window()->Minimize(); |
| break; |
| case IDC_MAXIMIZE_WINDOW: |
| browser_->window()->Maximize(); |
| break; |
| case IDC_RESTORE_WINDOW: |
| browser_->window()->Restore(); |
| break; |
| case IDC_USE_SYSTEM_TITLE_BAR: { |
| PrefService* prefs = profile()->GetPrefs(); |
| prefs->SetBoolean(prefs::kUseCustomChromeFrame, |
| !prefs->GetBoolean(prefs::kUseCustomChromeFrame)); |
| break; |
| } |
| #endif |
| |
| #if BUILDFLAG(IS_MAC) |
| case IDC_TOGGLE_FULLSCREEN_TOOLBAR: |
| chrome::ToggleAlwaysShowToolbarInFullscreen(browser_); |
| break; |
| case IDC_TOGGLE_JAVASCRIPT_APPLE_EVENTS: { |
| chrome::ToggleJavaScriptFromAppleEventsAllowed(browser_); |
| break; |
| } |
| #endif |
| case IDC_EXIT: |
| Exit(); |
| break; |
| |
| // Page-related commands |
| case IDC_SAVE_PAGE: |
| SavePage(browser_); |
| break; |
| case IDC_BOOKMARK_THIS_TAB: |
| BookmarkCurrentTab(browser_); |
| break; |
| case IDC_BOOKMARK_ALL_TABS: |
| BookmarkAllTabs(browser_); |
| break; |
| case IDC_VIEW_SOURCE: |
| browser_->tab_strip_model() |
| ->GetActiveWebContents() |
| ->GetPrimaryMainFrame() |
| ->ViewSource(); |
| break; |
| case IDC_PRINT: |
| Print(browser_); |
| break; |
| |
| #if BUILDFLAG(ENABLE_PRINTING) |
| case IDC_BASIC_PRINT: |
| base::RecordAction(base::UserMetricsAction("Accel_Advanced_Print")); |
| BasicPrint(browser_); |
| break; |
| #endif // ENABLE_PRINTING |
| case IDC_OFFERS_AND_REWARDS_FOR_PAGE: |
| ShowOffersAndRewardsForPage(browser_); |
| break; |
| case IDC_SAVE_CREDIT_CARD_FOR_PAGE: |
| SaveCreditCard(browser_); |
| break; |
| case IDC_SAVE_IBAN_FOR_PAGE: |
| SaveIban(browser_); |
| break; |
| case IDC_AUTOFILL_MANDATORY_REAUTH: |
| ShowMandatoryReauthOptInPrompt(browser_); |
| break; |
| case IDC_SAVE_AUTOFILL_ADDRESS: |
| SaveAutofillAddress(browser_); |
| break; |
| case IDC_SHOW_SYNC_SETTINGS: |
| chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage); |
| break; |
| case IDC_TURN_ON_SYNC: |
| signin_ui_util::EnableSyncFromSingleAccountPromo( |
| browser_->profile(), GetAccountInfoFromProfile(browser_->profile()), |
| signin_metrics::AccessPoint::kMenu); |
| break; |
| case IDC_SHOW_SIGNIN_WHEN_PAUSED: |
| signin_ui_util::ShowReauthForPrimaryAccountWithAuthError( |
| browser_->profile(), signin_metrics::AccessPoint::kMenu); |
| break; |
| case IDC_SHOW_PASSWORD_MANAGER: |
| ShowPasswordManager(browser_); |
| break; |
| case IDC_SAFETY_HUB_SHOW_PASSWORD_CHECKUP: |
| ShowPasswordCheck(browser_); |
| break; |
| case IDC_SHOW_PAYMENT_METHODS: |
| ShowPaymentMethods(browser_); |
| break; |
| case IDC_SHOW_ADDRESSES: |
| ShowAddresses(browser_); |
| break; |
| case IDC_FILLED_CARD_INFORMATION: |
| ShowFilledCardInformationBubble(browser_); |
| break; |
| case IDC_VIRTUAL_CARD_ENROLL: |
| ShowVirtualCardEnrollBubble(browser_); |
| break; |
| case IDC_ORGANIZE_TABS: |
| StartTabOrganizationRequest(browser_); |
| break; |
| case IDC_DECLUTTER_TABS: |
| ShowTabDeclutter(browser_); |
| break; |
| case IDC_SEND_SHARED_TAB_GROUP_FEEDBACK: |
| OpenFeedbackDialog(browser_, feedback::kFeedbackSourceDesktopTabGroups, |
| /*description_template=*/std::string(), |
| /*category_tag=*/"tab_group_share"); |
| break; |
| case IDC_SHOW_TRANSLATE: |
| ShowTranslateBubble(browser_); |
| break; |
| case IDC_MANAGE_PASSWORDS_FOR_PAGE: |
| ManagePasswordsForPage(browser_); |
| break; |
| case IDC_SEND_TAB_TO_SELF: |
| SendTabToSelf(browser_); |
| break; |
| case IDC_QRCODE_GENERATOR: |
| GenerateQRCode(browser_); |
| break; |
| case IDC_SHARING_HUB: |
| SharingHub(browser_); |
| break; |
| case IDC_SHARING_HUB_SCREENSHOT: |
| ScreenshotCapture(browser_); |
| break; |
| |
| // Clipboard commands |
| case IDC_CUT: |
| InvokeAction(actions::kActionCut, |
| browser_->GetActions()->root_action_item()); |
| break; |
| case IDC_COPY: |
| InvokeAction(actions::kActionCopy, |
| browser_->GetActions()->root_action_item()); |
| break; |
| case IDC_PASTE: |
| InvokeAction(actions::kActionPaste, |
| browser_->GetActions()->root_action_item()); |
| break; |
| |
| // Find-in-page |
| case IDC_FIND: |
| Find(browser_); |
| break; |
| case IDC_FIND_NEXT: |
| FindNext(browser_); |
| break; |
| case IDC_FIND_PREVIOUS: |
| FindPrevious(browser_); |
| break; |
| case IDC_CLOSE_FIND_OR_STOP: |
| if (CanCloseFind(browser_)) { |
| CloseFind(browser_); |
| } else if (IsCommandEnabled(IDC_STOP)) { |
| ExecuteCommand(IDC_STOP); |
| } |
| break; |
| |
| // Zoom |
| case IDC_ZOOM_PLUS: |
| Zoom(browser_, content::PAGE_ZOOM_IN); |
| break; |
| case IDC_ZOOM_NORMAL: |
| Zoom(browser_, content::PAGE_ZOOM_RESET); |
| break; |
| case IDC_ZOOM_MINUS: |
| Zoom(browser_, content::PAGE_ZOOM_OUT); |
| break; |
| |
| // Focus various bits of UI |
| case IDC_FOCUS_TOOLBAR: |
| base::RecordAction(base::UserMetricsAction("Accel_Focus_Toolbar")); |
| FocusToolbar(browser_); |
| break; |
| case IDC_FOCUS_LOCATION: |
| if (!window()->IsLocationBarVisible()) { |
| break; |
| } |
| base::RecordAction(base::UserMetricsAction("Accel_Focus_Location")); |
| FocusLocationBar(browser_); |
| break; |
| case IDC_FOCUS_SEARCH: |
| base::RecordAction(base::UserMetricsAction("Accel_Focus_Search")); |
| FocusSearch(browser_); |
| break; |
| case IDC_FOCUS_MENU_BAR: |
| FocusAppMenu(browser_); |
| break; |
| case IDC_FOCUS_BOOKMARKS: |
| base::RecordAction(base::UserMetricsAction("Accel_Focus_Bookmarks")); |
| FocusBookmarksToolbar(browser_); |
| break; |
| case IDC_FOCUS_INACTIVE_POPUP_FOR_ACCESSIBILITY: |
| FocusInactivePopupForAccessibility(browser_); |
| break; |
| case IDC_FOCUS_NEXT_PANE: |
| FocusNextPane(browser_); |
| break; |
| case IDC_FOCUS_PREVIOUS_PANE: |
| FocusPreviousPane(browser_); |
| break; |
| case IDC_FOCUS_WEB_CONTENTS_PANE: |
| FocusWebContentsPane(browser_); |
| break; |
| |
| // Show various bits of UI |
| case IDC_OPEN_FILE: |
| browser_->OpenFile(); |
| break; |
| case IDC_CREATE_SHORTCUT: |
| base::RecordAction(base::UserMetricsAction("CreateShortcut")); |
| #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) |
| chrome::CreateDesktopShortcutForActiveWebContents(browser_); |
| #else |
| web_app::CreateWebAppFromCurrentWebContents( |
| browser_, web_app::WebAppInstallFlow::kCreateShortcut); |
| #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) |
| break; |
| case IDC_INSTALL_PWA: |
| base::RecordAction(base::UserMetricsAction("InstallWebAppFromMenu")); |
| web_app::CreateWebAppFromCurrentWebContents( |
| browser_, web_app::WebAppInstallFlow::kInstallSite); |
| break; |
| case IDC_DEV_TOOLS: |
| ToggleDevToolsWindow(browser_, DevToolsToggleAction::Show(), |
| DevToolsOpenedByAction::kMainMenuOrMainShortcut); |
| break; |
| case IDC_DEV_TOOLS_CONSOLE: |
| ToggleDevToolsWindow(browser_, DevToolsToggleAction::ShowConsolePanel(), |
| DevToolsOpenedByAction::kConsoleShortcut); |
| break; |
| case IDC_DEV_TOOLS_DEVICES: |
| InspectUI::InspectDevices(browser_); |
| break; |
| case IDC_DEV_TOOLS_INSPECT: |
| ToggleDevToolsWindow(browser_, DevToolsToggleAction::Inspect(), |
| DevToolsOpenedByAction::kInspectorModeShortcut); |
| break; |
| case IDC_DEV_TOOLS_TOGGLE: |
| ToggleDevToolsWindow(browser_, DevToolsToggleAction::Toggle(), |
| DevToolsOpenedByAction::kToggleShortcut); |
| break; |
| case IDC_TASK_MANAGER: |
| OpenTaskManager(browser_); |
| break; |
| case IDC_TASK_MANAGER_APP_MENU: |
| OpenTaskManager(browser_, task_manager::StartAction::kMoreTools); |
| break; |
| case IDC_TASK_MANAGER_SHORTCUT: |
| OpenTaskManager(browser_, task_manager::StartAction::kShortcut); |
| break; |
| case IDC_TASK_MANAGER_CONTEXT_MENU: |
| OpenTaskManager(browser_, task_manager::StartAction::kContextMenu); |
| break; |
| case IDC_TASK_MANAGER_MAIN_MENU: |
| OpenTaskManager(browser_, task_manager::StartAction::kMainMenu); |
| break; |
| #if BUILDFLAG(GOOGLE_CHROME_BRANDING) |
| case IDC_FEEDBACK: |
| OpenFeedbackDialog(browser_, feedback::kFeedbackSourceBrowserCommand); |
| break; |
| #endif |
| case IDC_SHOW_CHROME_LABS: |
| window()->ShowChromeLabs(); |
| break; |
| case IDC_SHOW_BOOKMARK_BAR: |
| ToggleBookmarkBar(browser_); |
| break; |
| case IDC_SHOW_ALL_COMPARISON_TABLES: |
| ShowAllComparisonTables(browser_); |
| break; |
| case IDC_SHOW_FULL_URLS: |
| ToggleShowFullURLs(browser_); |
| break; |
| case IDC_SHOW_GOOGLE_LENS_SHORTCUT: |
| ToggleShowGoogleLensShortcut(browser_); |
| break; |
| case IDC_SHOW_SEARCH_TOOLS: |
| ToggleShowSearchTools(browser_); |
| break; |
| case IDC_PROFILING_ENABLED: |
| content::Profiling::Toggle(); |
| break; |
| case IDC_CARET_BROWSING_TOGGLE: |
| ToggleCaretBrowsing(browser_); |
| break; |
| case IDC_RECENT_TABS_LOGIN_FOR_DEVICE_TABS: |
| ShowSettingsSubPage(browser_->GetBrowserForOpeningWebUi(), |
| chrome::kPeopleSubPage); |
| break; |
| case IDC_SHOW_BOOKMARK_MANAGER: |
| ShowBookmarkManager(browser_->GetBrowserForOpeningWebUi()); |
| break; |
| case IDC_SHOW_BOOKMARK_SIDE_PANEL: |
| browser_->GetFeatures().side_panel_ui()->Show( |
| SidePanelEntryId::kBookmarks, SidePanelOpenTrigger::kAppMenu); |
| break; |
| case IDC_SHOW_APP_MENU: |
| base::RecordAction(base::UserMetricsAction("Accel_Show_App_Menu")); |
| ShowAppMenu(browser_); |
| break; |
| case IDC_SHOW_AVATAR_MENU: |
| ShowAvatarMenu(browser_); |
| break; |
| case IDC_SHOW_HISTORY: |
| ShowHistory(browser_->GetBrowserForOpeningWebUi()); |
| break; |
| case IDC_SHOW_HISTORY_CLUSTERS_SIDE_PANEL: |
| browser_->GetFeatures().side_panel_ui()->Show( |
| SidePanelEntryId::kHistoryClusters, SidePanelOpenTrigger::kAppMenu); |
| break; |
| case IDC_SHOW_DOWNLOADS: |
| ShowDownloads(browser_->GetBrowserForOpeningWebUi()); |
| break; |
| case IDC_MANAGE_EXTENSIONS: |
| case IDC_SAFETY_HUB_MANAGE_EXTENSIONS: |
| ShowExtensions(browser_->GetBrowserForOpeningWebUi()); |
| break; |
| case IDC_EXTENSIONS_SUBMENU_MANAGE_EXTENSIONS: |
| ShowExtensions(browser_->GetBrowserForOpeningWebUi()); |
| break; |
| case IDC_EXTENSIONS_SUBMENU_VISIT_CHROME_WEB_STORE: |
| case IDC_FIND_EXTENSIONS: |
| ShowWebStore(browser_, extension_urls::kAppMenuUtmSource); |
| break; |
| case IDC_PERFORMANCE: |
| ShowSettingsSubPage(browser_->GetBrowserForOpeningWebUi(), |
| chrome::kPerformanceSubPage); |
| break; |
| case IDC_OPTIONS: |
| ShowSettings(browser_->GetBrowserForOpeningWebUi()); |
| break; |
| case IDC_EDIT_SEARCH_ENGINES: |
| ShowSearchEngineSettings(browser_->GetBrowserForOpeningWebUi()); |
| break; |
| case IDC_VIEW_PASSWORDS: |
| NavigateToManagePasswordsPage( |
| browser_->GetBrowserForOpeningWebUi(), |
| password_manager::ManagePasswordsReferrer::kChromeMenuItem); |
| break; |
| case IDC_CLEAR_BROWSING_DATA: { |
| if (profile()->IsIncognitoProfile()) { |
| ShowIncognitoClearBrowsingDataDialog( |
| browser_->GetBrowserForOpeningWebUi()); |
| } else { |
| ShowClearBrowsingDataDialog(browser_->GetBrowserForOpeningWebUi()); |
| } |
| break; |
| } |
| case IDC_IMPORT_SETTINGS: |
| ShowImportDialog(browser_); |
| break; |
| case IDC_TOGGLE_REQUEST_TABLET_SITE: |
| ToggleRequestTabletSite(browser_); |
| break; |
| case IDC_ABOUT: |
| ShowAboutChrome(browser_->GetBrowserForOpeningWebUi()); |
| break; |
| case IDC_UPGRADE_DIALOG: |
| OpenUpdateChromeDialog(browser_); |
| break; |
| case IDC_OPEN_SAFETY_HUB: |
| ShowSettingsSubPage(browser_->GetBrowserForOpeningWebUi(), |
| chrome::kSafetyHubSubPage); |
| break; |
| case IDC_HELP_PAGE_VIA_KEYBOARD: |
| ShowHelp(browser_, HELP_SOURCE_KEYBOARD); |
| break; |
| case IDC_HELP_PAGE_VIA_MENU: |
| ShowHelp(browser_, HELP_SOURCE_MENU); |
| break; |
| case IDC_CHROME_TIPS: |
| #if BUILDFLAG(GOOGLE_CHROME_BRANDING) |
| ShowChromeTips(browser_); |
| break; |
| #else |
| NOTREACHED(); |
| #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) |
| case IDC_CHROME_WHATS_NEW: |
| #if BUILDFLAG(GOOGLE_CHROME_BRANDING) && \ |
| (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)) |
| ShowChromeWhatsNew(browser_); |
| break; |
| #else |
| NOTREACHED(); |
| #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) && \ |
| // (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)) |
| case IDC_SHOW_BETA_FORUM: |
| ShowBetaForum(browser_); |
| break; |
| case IDC_ROUTE_MEDIA: |
| RouteMediaInvokedFromAppMenu(browser_); |
| break; |
| case IDC_WINDOW_MUTE_SITE: |
| MuteSite(browser_); |
| break; |
| case IDC_WINDOW_PIN_TAB: |
| PinTab(browser_); |
| break; |
| case IDC_WINDOW_GROUP_TAB: |
| GroupTab(browser_); |
| break; |
| |
| // Tab group commands. |
| case IDC_FOCUS_NEXT_TAB_GROUP: |
| if (base::i18n::IsRTL()) { |
| FocusPreviousTabGroup(browser_); |
| } else { |
| FocusNextTabGroup(browser_); |
| } |
| base::UmaHistogramEnumeration("TabGroups.Shortcuts", |
| TabGroupShortcut::kFocusNextTabGroup); |
| break; |
| case IDC_FOCUS_PREV_TAB_GROUP: |
| if (base::i18n::IsRTL()) { |
| FocusNextTabGroup(browser_); |
| } else { |
| FocusPreviousTabGroup(browser_); |
| } |
| base::UmaHistogramEnumeration("TabGroups.Shortcuts", |
| TabGroupShortcut::kFocusPrevTabGroup); |
| break; |
| case IDC_CLOSE_TAB_GROUP: |
| CloseTabGroup(browser_); |
| base::UmaHistogramEnumeration("TabGroups.Shortcuts", |
| TabGroupShortcut::kCloseTabGroup); |
| break; |
| case IDC_CREATE_NEW_TAB_GROUP: |
| CreateNewTabGroup(browser_); |
| base::UmaHistogramEnumeration("TabGroups.Shortcuts", |
| TabGroupShortcut::kCreateNewTabGroup); |
| break; |
| case IDC_ADD_NEW_TAB_TO_GROUP: |
| AddNewTabToGroup(browser_); |
| base::UmaHistogramEnumeration("TabGroups.Shortcuts", |
| TabGroupShortcut::kAddNewTabToGroup); |
| break; |
| |
| case IDC_WINDOW_CLOSE_TABS_TO_RIGHT: |
| CloseTabsToRight(browser_); |
| break; |
| case IDC_WINDOW_CLOSE_OTHER_TABS: |
| CloseOtherTabs(browser_); |
| break; |
| case IDC_SHOW_MANAGEMENT_PAGE: { |
| ShowSingletonTab(browser_, GetManagedUiUrl(profile())); |
| break; |
| } |
| case IDC_MUTE_TARGET_SITE: |
| MuteSiteForKeyboardFocusedTab(browser_); |
| break; |
| case IDC_PIN_TARGET_TAB: |
| PinKeyboardFocusedTab(browser_); |
| break; |
| case IDC_GROUP_TARGET_TAB: |
| GroupKeyboardFocusedTab(browser_); |
| break; |
| case IDC_DUPLICATE_TARGET_TAB: |
| DuplicateKeyboardFocusedTab(browser_); |
| break; |
| // Hosted App commands |
| case IDC_COPY_URL: |
| CopyURL(browser_, browser_->tab_strip_model()->GetActiveWebContents()); |
| break; |
| case IDC_OPEN_IN_CHROME: |
| OpenInChrome(browser_); |
| break; |
| case IDC_WEB_APP_SETTINGS: |
| #if !BUILDFLAG(IS_CHROMEOS) |
| CHECK(browser_->app_controller()); |
| ShowWebAppSettings(browser_, browser_->app_controller()->app_id(), |
| web_app::AppSettingsPageEntryPoint::kBrowserCommand); |
| #endif |
| break; |
| case IDC_WEB_APP_MENU_APP_INFO: { |
| content::WebContents* const web_contents = |
| browser_->tab_strip_model()->GetActiveWebContents(); |
| if (web_contents) { |
| ShowPageInfoDialog( |
| web_contents, |
| base::BindOnce(&AppInfoDialogClosedCallback, |
| sessions::SessionTabHelper::IdForWindowContainingTab( |
| web_contents)), |
| bubble_anchor_util::Anchor::kAppMenuButton); |
| } |
| break; |
| } |
| |
| // UI debug commands |
| case IDC_DEBUG_TOGGLE_TABLET_MODE: |
| case IDC_DEBUG_PRINT_VIEW_TREE: |
| case IDC_DEBUG_PRINT_VIEW_TREE_DETAILS: |
| ExecuteUIDebugCommand(id, browser_); |
| break; |
| |
| case IDC_CONTENT_CONTEXT_LENS_OVERLAY: |
| ExecLensOverlay(browser_); |
| break; |
| |
| #if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES) |
| case IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH: |
| ExecLensRegionSearch(browser_); |
| break; |
| #endif // BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES) |
| case IDC_READING_LIST_MENU_ADD_TAB: |
| chrome::MoveCurrentTabToReadLater(browser_); |
| break; |
| |
| case IDC_READING_LIST_MENU_SHOW_UI: |
| browser_->GetFeatures().side_panel_ui()->Show( |
| SidePanelEntryId::kReadingList, SidePanelOpenTrigger::kAppMenu); |
| break; |
| |
| case IDC_SHOW_READING_MODE_SIDE_PANEL: { |
| // Yes. This is a separate feature from the reading list. |
| browser_->GetFeatures().side_panel_ui()->Show( |
| SidePanelEntryId::kReadAnything, SidePanelOpenTrigger::kAppMenu); |
| break; |
| } |
| |
| case IDC_SHOW_CUSTOMIZE_CHROME_SIDE_PANEL: { |
| ShowCustomizeChromeSidePanel(CustomizeChromeSection::kAppearance); |
| break; |
| } |
| |
| case IDC_SHOW_CUSTOMIZE_CHROME_TOOLBAR: { |
| ShowCustomizeChromeSidePanel(CustomizeChromeSection::kToolbar); |
| break; |
| } |
| |
| #if !BUILDFLAG(IS_CHROMEOS) |
| // Profile submenu commands |
| // This menu item is not enabled on ChromeOS and certain capabilities such |
| // as the profile picker are not available. |
| case IDC_CUSTOMIZE_CHROME: |
| chrome::ShowSettingsSubPage(browser_, chrome::kManageProfileSubPage); |
| break; |
| case IDC_CLOSE_PROFILE: { |
| if (browser_->profile()->IsIncognitoProfile()) { |
| BrowserList::CloseAllBrowsersWithIncognitoProfile( |
| browser_->profile(), base::DoNothing(), base::DoNothing(), true); |
| } else { |
| profiles::CloseProfileWindows(browser_->profile()); |
| } |
| break; |
| } |
| case IDC_MANAGE_GOOGLE_ACCOUNT: { |
| Profile* profile = browser_->profile(); |
| signin::IdentityManager* identity_manager = |
| IdentityManagerFactory::GetForProfile(profile); |
| DCHECK( |
| identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)); |
| NavigateToGoogleAccountPage( |
| profile, |
| identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin) |
| .email); |
| break; |
| } |
| case IDC_OPEN_GUEST_PROFILE: |
| profiles::SwitchToGuestProfile(); |
| break; |
| case IDC_ADD_NEW_PROFILE: |
| ProfilePicker::Show(ProfilePicker::Params::FromEntryPoint( |
| ProfilePicker::EntryPoint::kAppMenuProfileSubMenuAddNewProfile)); |
| break; |
| case IDC_MANAGE_CHROME_PROFILES: |
| ProfilePicker::Show(ProfilePicker::Params::FromEntryPoint( |
| ProfilePicker::EntryPoint::kAppMenuProfileSubMenuManageProfiles)); |
| break; |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) |
| case IDC_SET_BROWSER_AS_DEFAULT: |
| base::MakeRefCounted<shell_integration::DefaultBrowserWorker>() |
| ->StartSetAsDefault(base::DoNothing()); |
| |
| // Log metrics before clearing prefs and closing prompts. |
| if (g_browser_process->local_state()->HasPrefPath( |
| prefs::kDefaultBrowserFirstShownTime)) { |
| base::UmaHistogramCounts100( |
| "DefaultBrowser.AppMenu.TimesShownBeforeAccept", |
| g_browser_process->local_state()->GetInteger( |
| prefs::kDefaultBrowserDeclinedCount) + |
| 1); |
| } |
| chrome::startup::default_prompt::UpdatePrefsForDismissedPrompt( |
| browser_->profile()); |
| DefaultBrowserPromptManager::GetInstance()->CloseAllPrompts( |
| DefaultBrowserPromptManager::CloseReason::kAccept); |
| break; |
| #endif |
| #if BUILDFLAG(ENABLE_GLIC) |
| case IDC_GLIC_TOGGLE_PIN: { |
| PrefService* profile_prefs = profile()->GetPrefs(); |
| profile_prefs->SetBoolean( |
| glic::prefs::kGlicPinnedToTabstrip, |
| !profile_prefs->GetBoolean(glic::prefs::kGlicPinnedToTabstrip)); |
| break; |
| } |
| case IDC_OPEN_GLIC: { |
| auto* service = |
| glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile()); |
| if (service) { |
| glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile())->ToggleUI( |
| browser_, |
| /*prevent_close=*/true, |
| glic::mojom::InvocationSource::kThreeDotsMenu); |
| } |
| break; |
| } |
| #endif |
| default: |
| LOG(WARNING) << "Received Unimplemented Command: " << id; |
| break; |
| } |
| |
| return true; |
| } |
| |
| void BrowserCommandController::AddCommandObserver(int id, |
| CommandObserver* observer) { |
| command_updater_.AddCommandObserver(id, observer); |
| } |
| |
| void BrowserCommandController::RemoveCommandObserver( |
| int id, |
| CommandObserver* observer) { |
| command_updater_.RemoveCommandObserver(id, observer); |
| } |
| |
| void BrowserCommandController::RemoveCommandObserver( |
| CommandObserver* observer) { |
| command_updater_.RemoveCommandObserver(observer); |
| } |
| |
| bool BrowserCommandController::UpdateCommandEnabled(int id, bool state) { |
| // Block individual command updates in locked fullscreen mode unless the |
| // instance is locked for OnTask (only relevant for non-web browser |
| // scenarios). |
| // TODO(crbug.com/365146870): Remove once we consolidate locked fullscreen |
| // with OnTask. |
| bool should_block_command_update = is_locked_fullscreen_; |
| #if BUILDFLAG(IS_CHROMEOS) |
| if (browser_->IsLockedForOnTask()) { |
| should_block_command_update = false; |
| } |
| #endif |
| if (should_block_command_update) { |
| return false; |
| } |
| |
| return command_updater_.UpdateCommandEnabled(id, state); |
| } |
| |
| // BrowserCommandController, TabStripModelObserver implementation: |
| |
| void BrowserCommandController::OnTabStripModelChanged( |
| TabStripModel* tab_strip_model, |
| const TabStripModelChange& change, |
| const TabStripSelectionChange& selection) { |
| UpdateCommandsForTabStripStateChanged(); |
| } |
| |
| void BrowserCommandController::TabBlockedStateChanged( |
| content::WebContents* contents, |
| int index) { |
| PrintingStateChanged(); |
| FullscreenStateChanged(); |
| UpdateCommandsForFind(); |
| UpdateCommandsForMediaRouter(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // BrowserCommandController, TabRestoreServiceObserver implementation: |
| |
| void BrowserCommandController::TabRestoreServiceChanged( |
| sessions::TabRestoreService* service) { |
| UpdateTabRestoreCommandState(); |
| } |
| |
| void BrowserCommandController::TabRestoreServiceDestroyed( |
| sessions::TabRestoreService* service) { |
| service->RemoveObserver(this); |
| } |
| |
| void BrowserCommandController::TabRestoreServiceLoaded( |
| sessions::TabRestoreService* service) { |
| UpdateTabRestoreCommandState(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // BrowserCommandController, private: |
| |
| bool BrowserCommandController::IsShowingMainUI() { |
| return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP); |
| } |
| |
| bool BrowserCommandController::IsShowingLocationBar() { |
| return browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR); |
| } |
| |
| void BrowserCommandController::InitCommandState() { |
| // All browser commands whose state isn't set automagically some other way |
| // (like Back & Forward with initial page load) must have their state |
| // initialized here, otherwise they will be forever disabled. |
| |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| // Navigation commands |
| const bool can_reload = CanReload(browser_); |
| command_updater_.UpdateCommandEnabled(IDC_RELOAD, can_reload); |
| command_updater_.UpdateCommandEnabled(IDC_RELOAD_BYPASSING_CACHE, can_reload); |
| command_updater_.UpdateCommandEnabled(IDC_RELOAD_CLEARING_CACHE, can_reload); |
| |
| // Tab group commands |
| command_updater_.UpdateCommandEnabled(IDC_ADD_NEW_TAB_TO_GROUP, true); |
| command_updater_.UpdateCommandEnabled(IDC_CREATE_NEW_TAB_GROUP, true); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_NEXT_TAB_GROUP, true); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_PREV_TAB_GROUP, true); |
| command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB_GROUP, true); |
| |
| // Omnibox commands |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_FULL_URLS, true); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_GOOGLE_LENS_SHORTCUT, true); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_SEARCH_TOOLS, true); |
| |
| // Window management commands |
| command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true); |
| command_updater_.UpdateCommandEnabled( |
| IDC_NEW_TAB, !browser_->app_controller() || |
| !browser_->app_controller()->ShouldHideNewTabButton()); |
| command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true); |
| command_updater_.UpdateCommandEnabled( |
| IDC_DUPLICATE_TAB, !browser_->is_type_picture_in_picture()); |
| UpdateTabRestoreCommandState(); |
| command_updater_.UpdateCommandEnabled(IDC_EXIT, true); |
| command_updater_.UpdateCommandEnabled(IDC_NAME_WINDOW, true); |
| command_updater_.UpdateCommandEnabled(IDC_ORGANIZE_TABS, true); |
| command_updater_.UpdateCommandEnabled(IDC_DECLUTTER_TABS, true); |
| #if BUILDFLAG(IS_CHROMEOS) |
| command_updater_.UpdateCommandEnabled(IDC_TOGGLE_MULTITASK_MENU, true); |
| command_updater_.UpdateCommandEnabled(IDC_MINIMIZE_WINDOW, true); |
| // The VisitDesktop command is only supported for up to 5 logged in users |
| // because that's the max number of user sessions. If that number is increased |
| // the IDC_VISIT_DESKTOP_OF_LRU_USER_ command ids should be updated as well. |
| // crbug.com/940461 |
| static_assert( |
| session_manager::kMaximumNumberOfUserSessions <= |
| IDC_VISIT_DESKTOP_OF_LRU_USER_LAST - |
| IDC_VISIT_DESKTOP_OF_LRU_USER_NEXT + 2, |
| "The max number of user sessions exceeds the number of users supported."); |
| command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_2, true); |
| command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_3, true); |
| command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_4, true); |
| command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_5, true); |
| #endif |
| #if BUILDFLAG(IS_LINUX) |
| command_updater_.UpdateCommandEnabled(IDC_MINIMIZE_WINDOW, true); |
| command_updater_.UpdateCommandEnabled(IDC_MAXIMIZE_WINDOW, true); |
| command_updater_.UpdateCommandEnabled(IDC_RESTORE_WINDOW, true); |
| |
| bool use_system_title_bar = true; |
| #if BUILDFLAG(IS_OZONE) |
| use_system_title_bar = ui::OzonePlatform::GetInstance() |
| ->GetPlatformRuntimeProperties() |
| .supports_server_side_window_decorations; |
| #endif |
| command_updater_.UpdateCommandEnabled(IDC_USE_SYSTEM_TITLE_BAR, |
| use_system_title_bar); |
| #endif // BUILDFLAG(IS_LINUX) |
| command_updater_.UpdateCommandEnabled(IDC_OPEN_IN_PWA_WINDOW, |
| web_app::CanPopOutWebApp(profile())); |
| |
| // Page-related commands |
| command_updater_.UpdateCommandEnabled(IDC_MANAGE_PASSWORDS_FOR_PAGE, true); |
| |
| // Zoom |
| command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true); |
| command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true); |
| command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, false); |
| command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true); |
| |
| // Show various bits of UI |
| DCHECK(!profile()->IsSystemProfile()) |
| << "Ought to never have browser for the system profile."; |
| const bool normal_window = browser_->is_type_normal(); |
| const bool guest_session = profile()->IsGuestSession(); |
| command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, CanOpenFile(browser_)); |
| UpdateCommandsForDevTools(); |
| command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, CanOpenTaskManager()); |
| command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER_APP_MENU, |
| CanOpenTaskManager()); |
| command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER_SHORTCUT, |
| CanOpenTaskManager()); |
| command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER_CONTEXT_MENU, |
| CanOpenTaskManager()); |
| command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER_MAIN_MENU, |
| CanOpenTaskManager()); |
| command_updater_.UpdateCommandEnabled(IDC_PROFILE_MENU_IN_APP_MENU, true); |
| command_updater_.UpdateCommandEnabled( |
| IDC_SHOW_HISTORY, (!guest_session && !profile()->IsSystemProfile())); |
| command_updater_.UpdateCommandEnabled( |
| IDC_SHOW_HISTORY_CLUSTERS_SIDE_PANEL, |
| (!guest_session && !profile()->IsSystemProfile())); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true); |
| command_updater_.UpdateCommandEnabled(IDC_FIND_AND_EDIT_MENU, true); |
| command_updater_.UpdateCommandEnabled(IDC_SAVE_AND_SHARE_MENU, true); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_READING_MODE_SIDE_PANEL, true); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_CUSTOMIZE_CHROME_SIDE_PANEL, |
| true); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_CUSTOMIZE_CHROME_TOOLBAR, |
| true); |
| command_updater_.UpdateCommandEnabled(IDC_SEND_TAB_TO_SELF, false); |
| command_updater_.UpdateCommandEnabled(IDC_QRCODE_GENERATOR, false); |
| command_updater_.UpdateCommandEnabled(IDC_PASSWORDS_AND_AUTOFILL_MENU, |
| !guest_session); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_PASSWORD_MANAGER, |
| !guest_session); |
| command_updater_.UpdateCommandEnabled(IDC_SAFETY_HUB_SHOW_PASSWORD_CHECKUP, |
| !guest_session); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_PAYMENT_METHODS, |
| !guest_session); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETTINGS, true); |
| command_updater_.UpdateCommandEnabled(IDC_TURN_ON_SYNC, true); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_SIGNIN_WHEN_PAUSED, true); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_ADDRESSES, !guest_session); |
| command_updater_.UpdateCommandEnabled(IDC_HELP_MENU, true); |
| command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_KEYBOARD, true); |
| command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_MENU, true); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_BETA_FORUM, true); |
| command_updater_.UpdateCommandEnabled( |
| IDC_BOOKMARKS_MENU, (!guest_session && !profile()->IsSystemProfile())); |
| command_updater_.UpdateCommandEnabled(IDC_SAVED_TAB_GROUPS_MENU, true); |
| command_updater_.UpdateCommandEnabled( |
| IDC_RECENT_TABS_MENU, (!guest_session && !profile()->IsSystemProfile() && |
| !profile()->IsIncognitoProfile())); |
| command_updater_.UpdateCommandEnabled( |
| IDC_RECENT_TABS_LOGIN_FOR_DEVICE_TABS, |
| (!guest_session && !profile()->IsSystemProfile() && |
| !profile()->IsIncognitoProfile())); |
| #if !BUILDFLAG(IS_CHROMEOS) |
| command_updater_.UpdateCommandEnabled(IDC_CUSTOMIZE_CHROME, true); |
| command_updater_.UpdateCommandEnabled(IDC_CLOSE_PROFILE, true); |
| command_updater_.UpdateCommandEnabled(IDC_MANAGE_GOOGLE_ACCOUNT, true); |
| command_updater_.UpdateCommandEnabled(IDC_OPEN_GUEST_PROFILE, true); |
| command_updater_.UpdateCommandEnabled(IDC_ADD_NEW_PROFILE, true); |
| command_updater_.UpdateCommandEnabled(IDC_MANAGE_CHROME_PROFILES, true); |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| |
| if (profile()->IsIncognitoProfile()) { |
| command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, true); |
| } else { |
| command_updater_.UpdateCommandEnabled( |
| IDC_CLEAR_BROWSING_DATA, |
| (!guest_session && !profile()->IsSystemProfile())); |
| } |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| command_updater_.UpdateCommandEnabled(IDC_TAKE_SCREENSHOT, true); |
| // Chrome OS uses the system tray menu to handle multi-profiles. Avatar menu |
| // is only required in incognito mode. |
| command_updater_.UpdateCommandEnabled( |
| IDC_SHOW_AVATAR_MENU, /*state=*/profile()->IsIncognitoProfile()); |
| #else |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU, |
| /*state=*/normal_window); |
| #endif |
| command_updater_.UpdateCommandEnabled( |
| IDC_SHOW_SAVE_LOCAL_CARD_SIGN_IN_PROMO_IF_APPLICABLE, true); |
| command_updater_.UpdateCommandEnabled(IDC_CLOSE_SIGN_IN_PROMO, true); |
| command_updater_.UpdateCommandEnabled(IDC_CARET_BROWSING_TOGGLE, true); |
| // Navigation commands |
| command_updater_.UpdateCommandEnabled( |
| IDC_HOME, normal_window || browser_->is_type_app() || |
| browser_->is_type_app_popup()); |
| |
| // Hosted app browser commands. |
| const bool is_web_app_or_custom_tab = IsWebAppOrCustomTab(browser_); |
| const bool enable_copy_url = |
| is_web_app_or_custom_tab || |
| !sharing_hub::SharingIsDisabledByPolicy(browser_->profile()); |
| command_updater_.UpdateCommandEnabled(IDC_COPY_URL, enable_copy_url); |
| command_updater_.UpdateCommandEnabled(IDC_WEB_APP_SETTINGS, |
| is_web_app_or_custom_tab); |
| command_updater_.UpdateCommandEnabled(IDC_WEB_APP_MENU_APP_INFO, |
| is_web_app_or_custom_tab); |
| |
| // Tab management commands |
| const bool supports_tabs = |
| browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_NEW_TAB_TO_RIGHT, supports_tabs); |
| |
| // These are always enabled; the menu determines their menu item visibility. |
| command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true); |
| command_updater_.UpdateCommandEnabled(IDC_SET_BROWSER_AS_DEFAULT, true); |
| |
| // Safety Hub commands. |
| command_updater_.UpdateCommandEnabled(IDC_OPEN_SAFETY_HUB, true); |
| |
| command_updater_.UpdateCommandEnabled(IDC_WINDOW_MUTE_SITE, normal_window); |
| command_updater_.UpdateCommandEnabled(IDC_WINDOW_PIN_TAB, normal_window); |
| command_updater_.UpdateCommandEnabled(IDC_WINDOW_GROUP_TAB, normal_window); |
| command_updater_.UpdateCommandEnabled(IDC_WINDOW_CLOSE_TABS_TO_RIGHT, |
| normal_window); |
| command_updater_.UpdateCommandEnabled(IDC_WINDOW_CLOSE_OTHER_TABS, |
| normal_window); |
| |
| const bool enable_tab_search_commands = browser_->is_type_normal(); |
| command_updater_.UpdateCommandEnabled(IDC_TAB_SEARCH, |
| enable_tab_search_commands); |
| command_updater_.UpdateCommandEnabled(IDC_TAB_SEARCH_CLOSE, |
| enable_tab_search_commands); |
| |
| if (base::FeatureList::IsEnabled(features::kUIDebugTools)) { |
| command_updater_.UpdateCommandEnabled(IDC_DEBUG_TOGGLE_TABLET_MODE, true); |
| command_updater_.UpdateCommandEnabled(IDC_DEBUG_PRINT_VIEW_TREE, true); |
| command_updater_.UpdateCommandEnabled(IDC_DEBUG_PRINT_VIEW_TREE_DETAILS, |
| true); |
| } |
| |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_SIDE_PANEL, true); |
| |
| if (browser_->is_type_normal()) { |
| // Reading list commands. |
| command_updater_.UpdateCommandEnabled(IDC_READING_LIST_MENU, true); |
| command_updater_.UpdateCommandEnabled(IDC_READING_LIST_MENU_ADD_TAB, true); |
| command_updater_.UpdateCommandEnabled(IDC_READING_LIST_MENU_SHOW_UI, true); |
| } |
| if (IsChromeLabsEnabled()) { |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_CHROME_LABS, true); |
| } |
| |
| // Compare commands. |
| command_updater_.UpdateCommandEnabled(IDC_COMPARE_MENU, true); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_ALL_COMPARISON_TABLES, true); |
| command_updater_.UpdateCommandEnabled(IDC_ADD_TO_COMPARISON_TABLE_MENU, true); |
| command_updater_.UpdateCommandEnabled( |
| IDC_CREATE_NEW_COMPARISON_TABLE_WITH_TAB, true); |
| |
| #if BUILDFLAG(ENABLE_GLIC) |
| // Glic commands. |
| command_updater_.UpdateCommandEnabled( |
| IDC_GLIC_TOGGLE_PIN, glic::GlicEnabling::IsProfileEligible(profile())); |
| UpdateGlicState(); |
| #endif |
| |
| // Initialize other commands whose state changes based on various conditions. |
| UpdateCommandsForFullscreenMode(); |
| UpdateCommandsForContentRestrictionState(); |
| UpdateCommandsForBookmarkEditing(); |
| UpdateCommandsForIncognitoAvailability(); |
| UpdateCommandsForExtensionsMenu(); |
| UpdateCommandsForTabKeyboardFocus(GetKeyboardFocusedTabIndex(browser_)); |
| UpdateCommandsForWebContentsFocus(); |
| } |
| |
| // static |
| void BrowserCommandController::UpdateSharedCommandsForIncognitoAvailability( |
| CommandUpdater* command_updater, |
| Profile* profile) { |
| policy::IncognitoModeAvailability incognito_availability = |
| IncognitoModePrefs::GetAvailability(profile->GetPrefs()); |
| command_updater->UpdateCommandEnabled( |
| IDC_NEW_WINDOW, |
| incognito_availability != policy::IncognitoModeAvailability::kForced); |
| command_updater->UpdateCommandEnabled( |
| IDC_NEW_INCOGNITO_WINDOW, |
| incognito_availability != policy::IncognitoModeAvailability::kDisabled && |
| !profile->IsGuestSession()); |
| |
| const bool forced_incognito = |
| incognito_availability == policy::IncognitoModeAvailability::kForced; |
| const bool is_guest = profile->IsGuestSession(); |
| |
| command_updater->UpdateCommandEnabled( |
| IDC_SHOW_BOOKMARK_MANAGER, |
| browser_defaults::bookmarks_enabled && !forced_incognito && !is_guest); |
| extensions::ExtensionRegistrar* extension_registrar = |
| extensions::ExtensionRegistrar::Get(profile); |
| const bool enable_extensions = |
| extension_registrar && extension_registrar->extensions_enabled(); |
| |
| // Bookmark manager and settings page/subpages are forced to open in normal |
| // mode. For this reason we disable these commands when incognito is forced. |
| command_updater->UpdateCommandEnabled( |
| IDC_MANAGE_EXTENSIONS, |
| enable_extensions && !forced_incognito && !is_guest); |
| command_updater->UpdateCommandEnabled( |
| IDC_SAFETY_HUB_MANAGE_EXTENSIONS, |
| enable_extensions && !forced_incognito && !is_guest); |
| |
| command_updater->UpdateCommandEnabled(IDC_IMPORT_SETTINGS, |
| !forced_incognito && !is_guest); |
| command_updater->UpdateCommandEnabled(IDC_OPTIONS, |
| !forced_incognito || is_guest); |
| command_updater->UpdateCommandEnabled(IDC_PERFORMANCE, |
| !forced_incognito && !is_guest); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForIncognitoAvailability() { |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| UpdateSharedCommandsForIncognitoAvailability(&command_updater_, profile()); |
| // Update the new incognito window ActionItem enabled state. Note, this cannot |
| // be done in UpdateSharedCommandsForIncognitoAvailability as the method is |
| // static to also handle states for NSApplication where no browser window are |
| // open. |
| if (auto* const incognito_action = FindAction(kActionNewIncognitoWindow)) { |
| incognito_action->SetEnabled( |
| IncognitoModePrefs::IsIncognitoAllowed(profile())); |
| } |
| |
| if (!IsShowingMainUI()) { |
| command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, false); |
| command_updater_.UpdateCommandEnabled(IDC_OPTIONS, false); |
| } |
| } |
| |
| void BrowserCommandController::UpdateCommandsForExtensionsMenu() { |
| // TODO(crbug.com/41124423): Talk with isandrk@chromium.org about whether this |
| // is necessary for the experiment or not. |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| command_updater_.UpdateCommandEnabled( |
| IDC_EXTENSIONS_SUBMENU_MANAGE_EXTENSIONS, |
| /*state=*/true); |
| command_updater_.UpdateCommandEnabled( |
| IDC_EXTENSIONS_SUBMENU_VISIT_CHROME_WEB_STORE, /*state=*/true); |
| command_updater_.UpdateCommandEnabled(IDC_FIND_EXTENSIONS, |
| /*state=*/true); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForTabState() { |
| // Keep commands disabled when in locked fullscreen so users cannot exit this |
| // mode. Only update navigation ones when the webapp is locked for OnTask |
| // (only relevant for non-web browser scenarios). |
| // TODO(b/365146870): Remove once we consolidate locked fullscreen with |
| // OnTask. |
| bool skip_all_command_updates = is_locked_fullscreen_; |
| #if BUILDFLAG(IS_CHROMEOS) |
| if (browser_->IsLockedForOnTask()) { |
| skip_all_command_updates = false; |
| } |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| if (skip_all_command_updates) { |
| return; |
| } |
| |
| content::WebContents* current_web_contents = |
| browser_->tab_strip_model()->GetActiveWebContents(); |
| if (!current_web_contents) { // May be NULL during tab restore. |
| return; |
| } |
| |
| // Navigation commands |
| command_updater_.UpdateCommandEnabled(IDC_BACK, CanGoBack(browser_)); |
| command_updater_.UpdateCommandEnabled(IDC_FORWARD, CanGoForward(browser_)); |
| const bool can_reload = CanReload(browser_); |
| command_updater_.UpdateCommandEnabled(IDC_RELOAD, can_reload); |
| command_updater_.UpdateCommandEnabled(IDC_RELOAD_BYPASSING_CACHE, can_reload); |
| command_updater_.UpdateCommandEnabled(IDC_RELOAD_CLEARING_CACHE, can_reload); |
| if (is_locked_fullscreen_) { |
| // Skip other command updates. |
| // NOTE: If new commands are being added, please add them after this |
| // conditional and notify the ChromeOS team by filing a bug under this |
| // component -- b/?q=componentid:1389107. |
| return; |
| } |
| |
| // Window management commands |
| bool is_app = browser_->is_type_app() || browser_->is_type_app_popup(); |
| bool is_normal = browser_->is_type_normal(); |
| |
| command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, |
| !is_app && CanDuplicateTab(browser_)); |
| command_updater_.UpdateCommandEnabled(IDC_WINDOW_MUTE_SITE, !is_app); |
| command_updater_.UpdateCommandEnabled(IDC_WINDOW_PIN_TAB, is_normal); |
| command_updater_.UpdateCommandEnabled(IDC_WINDOW_GROUP_TAB, is_normal); |
| |
| // Page-related commands |
| window()->SetStarredState( |
| BookmarkTabHelper::FromWebContents(current_web_contents)->is_starred()); |
| window()->ZoomChangedForActiveTab(false); |
| command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE, |
| CanViewSource(browser_)); |
| |
| command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, CanOpenFile(browser_)); |
| |
| bool can_create_web_app = web_app::CanCreateWebApp(browser_); |
| command_updater_.UpdateCommandEnabled(IDC_INSTALL_PWA, can_create_web_app); |
| |
| #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) |
| command_updater_.UpdateCommandEnabled( |
| IDC_CREATE_SHORTCUT, |
| shortcuts::CanCreateDesktopShortcut(current_web_contents)); |
| #else |
| command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUT, |
| can_create_web_app); |
| #endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) |
| |
| UpdateCommandAndActionEnabled(IDC_SEND_TAB_TO_SELF, kActionSendTabToSelf, |
| CanSendTabToSelf(browser_)); |
| |
| UpdateCommandAndActionEnabled(IDC_QRCODE_GENERATOR, kActionQrCodeGenerator, |
| CanGenerateQrCode(browser_)); |
| |
| ChromeTranslateClient* chrome_translate_client = |
| ChromeTranslateClient::FromWebContents(current_web_contents); |
| const bool can_translate = |
| chrome_translate_client && |
| chrome_translate_client->GetTranslateManager()->CanManuallyTranslate(); |
| UpdateCommandAndActionEnabled(IDC_SHOW_TRANSLATE, kActionShowTranslate, |
| can_translate); |
| |
| bool is_isolated_app = browser_->app_controller() && |
| browser_->app_controller()->IsIsolatedWebApp(); |
| bool is_pinned_home_tab = web_app::IsPinnedHomeTab( |
| browser_->tab_strip_model(), browser_->tab_strip_model()->active_index()); |
| command_updater_.UpdateCommandEnabled( |
| IDC_OPEN_IN_CHROME, |
| IsWebAppOrCustomTab(browser_) && !is_isolated_app && !is_pinned_home_tab); |
| |
| command_updater_.UpdateCommandEnabled( |
| IDC_READING_LIST_MENU_ADD_TAB, |
| browser_->tab_strip_model()->IsReadLaterSupportedForAny( |
| {browser_->tab_strip_model()->active_index()})); |
| |
| command_updater_.UpdateCommandEnabled( |
| IDC_TOGGLE_REQUEST_TABLET_SITE, |
| CanRequestTabletSite(current_web_contents)); |
| |
| UpdateCommandsForContentRestrictionState(); |
| UpdateCommandsForBookmarkEditing(); |
| UpdateCommandsForFind(); |
| UpdateCommandsForMediaRouter(); |
| // Update the zoom commands when an active tab is selected. |
| UpdateCommandsForZoomState(); |
| UpdateCommandsForTabKeyboardFocus(GetKeyboardFocusedTabIndex(browser_)); |
| |
| // Disable the add to comparison table menu when the page is not a standard |
| // webpage. |
| command_updater_.UpdateCommandEnabled( |
| IDC_ADD_TO_COMPARISON_TABLE_MENU, |
| commerce::IsUrlEligibleForProductSpecs( |
| current_web_contents->GetLastCommittedURL())); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForZoomState() { |
| content::WebContents* contents = |
| browser_->tab_strip_model()->GetActiveWebContents(); |
| if (!contents) { |
| return; |
| } |
| command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, CanZoomIn(contents)); |
| command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, |
| CanResetZoom(contents)); |
| command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, CanZoomOut(contents)); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForContentRestrictionState() { |
| int restrictions = GetContentRestrictions(browser_); |
| |
| command_updater_.UpdateCommandEnabled( |
| IDC_COPY, !(restrictions & CONTENT_RESTRICTION_COPY)); |
| command_updater_.UpdateCommandEnabled( |
| IDC_CUT, !(restrictions & CONTENT_RESTRICTION_CUT)); |
| command_updater_.UpdateCommandEnabled( |
| IDC_PASTE, !(restrictions & CONTENT_RESTRICTION_PASTE)); |
| UpdateSaveAsState(); |
| UpdatePrintingState(); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForDevTools() { |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| bool dev_tools_enabled = DevToolsWindow::AllowDevToolsFor( |
| profile(), browser_->tab_strip_model()->GetActiveWebContents()); |
| command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS, dev_tools_enabled); |
| command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE, |
| dev_tools_enabled); |
| command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_DEVICES, |
| dev_tools_enabled); |
| command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT, |
| dev_tools_enabled); |
| command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_TOGGLE, |
| dev_tools_enabled); |
| command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE, dev_tools_enabled); |
| #if BUILDFLAG(IS_MAC) |
| command_updater_.UpdateCommandEnabled(IDC_TOGGLE_JAVASCRIPT_APPLE_EVENTS, |
| dev_tools_enabled); |
| #endif |
| } |
| |
| void BrowserCommandController::UpdateCommandsForBookmarkEditing() { |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_THIS_TAB, |
| CanBookmarkCurrentTab(browser_)); |
| command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS, |
| CanBookmarkAllTabs(browser_)); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForBookmarkBar() { |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| command_updater_.UpdateCommandEnabled( |
| IDC_SHOW_BOOKMARK_BAR, browser_defaults::bookmarks_enabled && |
| !profile()->IsGuestSession() && |
| !profile()->IsSystemProfile() && |
| !profile()->GetPrefs()->IsManagedPreference( |
| bookmarks::prefs::kShowBookmarkBar) && |
| IsShowingMainUI()); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForFileSelectionDialogs() { |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| UpdateSaveAsState(); |
| command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, CanOpenFile(browser_)); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForFullscreenMode() { |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| const bool is_fullscreen = window() && window()->IsFullscreen(); |
| const bool show_main_ui = IsShowingMainUI(); |
| const bool show_location_bar = IsShowingLocationBar(); |
| |
| const bool main_not_fullscreen = show_main_ui && !is_fullscreen; |
| |
| // Navigation commands |
| command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui); |
| |
| // Window management commands |
| command_updater_.UpdateCommandEnabled( |
| IDC_SHOW_AS_TAB, !browser_->is_type_normal() && !is_fullscreen && |
| !browser_->is_type_devtools() && |
| !browser_->is_type_picture_in_picture()); |
| |
| // Focus various bits of UI |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_location_bar); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_MENU_BAR, |
| main_not_fullscreen); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_NEXT_PANE, |
| main_not_fullscreen); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_PREVIOUS_PANE, |
| main_not_fullscreen); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_WEB_CONTENTS_PANE, |
| main_not_fullscreen); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_BOOKMARKS, |
| main_not_fullscreen); |
| command_updater_.UpdateCommandEnabled( |
| IDC_FOCUS_INACTIVE_POPUP_FOR_ACCESSIBILITY, main_not_fullscreen); |
| |
| // Show various bits of UI |
| command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui); |
| #if BUILDFLAG(GOOGLE_CHROME_BRANDING) |
| command_updater_.UpdateCommandEnabled( |
| IDC_FEEDBACK, show_main_ui || browser_->is_type_devtools()); |
| #endif |
| |
| command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui); |
| command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui); |
| command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui); |
| #if BUILDFLAG(GOOGLE_CHROME_BRANDING) |
| command_updater_.UpdateCommandEnabled(IDC_CHROME_TIPS, show_main_ui); |
| command_updater_.UpdateCommandEnabled(IDC_CHROME_WHATS_NEW, show_main_ui); |
| #endif |
| command_updater_.UpdateCommandEnabled(IDC_CONTENT_CONTEXT_SHARING_SUBMENU, |
| show_main_ui); |
| command_updater_.UpdateCommandEnabled(IDC_SHARING_HUB, show_main_ui); |
| command_updater_.UpdateCommandEnabled(IDC_SHARING_HUB_SCREENSHOT, |
| show_main_ui); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_MANAGEMENT_PAGE, true); |
| |
| if (base::debug::IsProfilingSupported()) { |
| command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui); |
| } |
| |
| #if !BUILDFLAG(IS_MAC) |
| // Disable toggling into fullscreen mode if disallowed by pref. |
| const bool fullscreen_enabled = |
| is_fullscreen || |
| profile()->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed); |
| #else |
| const bool fullscreen_enabled = true; |
| #endif |
| |
| command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN, fullscreen_enabled); |
| command_updater_.UpdateCommandEnabled(IDC_TOGGLE_FULLSCREEN_TOOLBAR, |
| fullscreen_enabled); |
| |
| UpdateCommandsForBookmarkBar(); |
| UpdateCommandsForIncognitoAvailability(); |
| UpdateCommandsForHostedAppAvailability(); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForHostedAppAvailability() { |
| bool has_toolbar = browser_->is_type_normal() || |
| web_app::AppBrowserController::IsWebApp(browser_); |
| if (window() && window()->ShouldHideUIForFullscreen()) { |
| has_toolbar = false; |
| } |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, has_toolbar); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_NEXT_PANE, has_toolbar); |
| command_updater_.UpdateCommandEnabled(IDC_FOCUS_PREVIOUS_PANE, has_toolbar); |
| command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, has_toolbar); |
| } |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| namespace { |
| |
| #if DCHECK_IS_ON() |
| // Makes sure that all commands that are not allowlisted are disabled. DCHECKs |
| // otherwise. Compiled only in debug mode. |
| void NonAllowlistedCommandsAreDisabled(CommandUpdaterImpl* command_updater) { |
| constexpr int kAllowlistedIds[] = {IDC_CUT, IDC_COPY, IDC_PASTE}; |
| |
| // Go through all the command ids, skip the allowlisted ones. |
| for (int id : command_updater->GetAllIds()) { |
| if (base::Contains(kAllowlistedIds, id)) { |
| continue; |
| } |
| DCHECK(!command_updater->IsCommandEnabled(id)); |
| } |
| } |
| #endif |
| |
| } // namespace |
| |
| void BrowserCommandController::UpdateCommandsForLockedFullscreenMode() { |
| bool is_locked_fullscreen = |
| platform_util::IsBrowserLockedFullscreen(browser_); |
| // Sanity check to make sure this function is called only on state change. |
| DCHECK_NE(is_locked_fullscreen, is_locked_fullscreen_); |
| if (is_locked_fullscreen == is_locked_fullscreen_) { |
| return; |
| } |
| is_locked_fullscreen_ = is_locked_fullscreen; |
| |
| if (is_locked_fullscreen_) { |
| command_updater_.DisableAllCommands(); |
| // Update the state of allowlisted commands: |
| // IDC_CUT/IDC_COPY/IDC_PASTE, |
| UpdateCommandsForContentRestrictionState(); |
| // TODO(crbug.com/41426009): Re-enable Find and Zoom in locked fullscreen. |
| // All other commands will be disabled (there is an early return in their |
| // corresponding UpdateCommandsFor* functions). |
| #if DCHECK_IS_ON() |
| NonAllowlistedCommandsAreDisabled(&command_updater_); |
| #endif |
| // Enable commands that allow users to switch between tabs and find content |
| // within a webpage if the webapp is locked for OnTask |
| // (only relevant for non-web browser scenarios). |
| if (browser_->IsLockedForOnTask()) { |
| bool supports_tabs = |
| browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, supports_tabs); |
| command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB, |
| supports_tabs); |
| UpdateCommandsForFind(); |
| } |
| } else { |
| // Do an init call to re-initialize command state after the |
| // DisableAllCommands. |
| InitCommandState(); |
| } |
| } |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| |
| void BrowserCommandController::UpdatePrintingState() { |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| UpdateCommandAndActionEnabled(IDC_PRINT, kActionPrint, CanPrint(browser_)); |
| #if BUILDFLAG(ENABLE_PRINTING) |
| command_updater_.UpdateCommandEnabled(IDC_BASIC_PRINT, |
| CanBasicPrint(browser_)); |
| #endif |
| } |
| |
| #if BUILDFLAG(ENABLE_GLIC) |
| void BrowserCommandController::UpdateGlicState() { |
| if (glic::GlicEnabling::IsEnabledByFlags()) { |
| auto* service = |
| glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile()); |
| if (service) { |
| command_updater_.UpdateCommandEnabled( |
| IDC_OPEN_GLIC, glic::GlicEnabling::IsEnabledForProfile(profile()) && |
| !service->window_controller().IsShowing()); |
| } |
| } |
| } |
| #endif |
| |
| void BrowserCommandController::UpdateSaveAsState() { |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, CanSavePage(browser_)); |
| } |
| |
| void BrowserCommandController::UpdateReloadStopState(bool is_loading, |
| bool force) { |
| // Skip command updates when in locked fullscreen mode unless the instance is |
| // locked for OnTask (only relevant for non-web browser scenarios). |
| // TODO(crbug.com/365146870): Remove once we consolidate locked fullscreen |
| // with OnTask. |
| bool should_skip_command_updates = is_locked_fullscreen_; |
| #if BUILDFLAG(IS_CHROMEOS) |
| if (browser_->IsLockedForOnTask()) { |
| should_skip_command_updates = false; |
| } |
| #endif |
| if (should_skip_command_updates) { |
| return; |
| } |
| |
| window()->UpdateReloadStopState(is_loading, force); |
| command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading); |
| UpdateCloseFindOrStop(); |
| } |
| |
| void BrowserCommandController::UpdateTabRestoreCommandState() { |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| sessions::TabRestoreService* tab_restore_service = |
| TabRestoreServiceFactory::GetForProfile(profile()); |
| // The command is enabled if the service hasn't loaded yet to trigger loading. |
| // The command is updated once the load completes. |
| command_updater_.UpdateCommandEnabled( |
| IDC_RESTORE_TAB, |
| tab_restore_service && (!tab_restore_service->IsLoaded() || |
| !tab_restore_service->entries().empty())); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForFind() { |
| TabStripModel* model = browser_->tab_strip_model(); |
| int active_index = model->active_index(); |
| |
| bool enabled = active_index != TabStripModel::kNoTab && |
| !model->IsTabBlocked(active_index) && |
| !browser_->is_type_devtools(); |
| |
| command_updater_.UpdateCommandEnabled(IDC_FIND, enabled); |
| command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, enabled); |
| command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, enabled); |
| } |
| |
| void BrowserCommandController::UpdateCloseFindOrStop() { |
| bool enabled = CanCloseFind(browser_) || IsCommandEnabled(IDC_STOP); |
| command_updater_.UpdateCommandEnabled(IDC_CLOSE_FIND_OR_STOP, enabled); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForMediaRouter() { |
| if (is_locked_fullscreen_) { |
| return; |
| } |
| |
| UpdateCommandAndActionEnabled(IDC_ROUTE_MEDIA, kActionRouteMedia, |
| CanRouteMedia(browser_)); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForTabKeyboardFocus( |
| std::optional<int> target_index) { |
| command_updater_.UpdateCommandEnabled( |
| IDC_DUPLICATE_TARGET_TAB, !browser_->is_type_app() && |
| !browser_->is_type_app_popup() && |
| target_index.has_value() && |
| CanDuplicateTabAt(browser_, *target_index)); |
| const bool normal_window = browser_->is_type_normal(); |
| command_updater_.UpdateCommandEnabled( |
| IDC_MUTE_TARGET_SITE, normal_window && target_index.has_value()); |
| command_updater_.UpdateCommandEnabled( |
| IDC_PIN_TARGET_TAB, normal_window && target_index.has_value()); |
| command_updater_.UpdateCommandEnabled( |
| IDC_GROUP_TARGET_TAB, normal_window && target_index.has_value()); |
| } |
| |
| void BrowserCommandController::UpdateCommandsForWebContentsFocus() { |
| #if BUILDFLAG(IS_MAC) |
| // On Mac, toggling caret browsing changes whether it's enabled or not |
| // based on web contents focus. |
| command_updater_.UpdateCommandEnabled(IDC_CARET_BROWSING_TOGGLE, |
| CanToggleCaretBrowsing(browser_)); |
| #endif // BUILDFLAG(IS_MAC) |
| } |
| |
| void BrowserCommandController::UpdateCommandsForTabStripStateChanged() { |
| if (is_locked_fullscreen_) { |
| // Keep tab management commands disabled when in locked fullscreen so users |
| // cannot exit this mode. Only relevant for non-web browser scenarios. |
| return; |
| } |
| |
| int tab_index = browser_->tab_strip_model()->active_index(); |
| // No commands are updated if there is not yet any selected tab. |
| if (tab_index == TabStripModel::kNoTab) { |
| return; |
| } |
| command_updater_.UpdateCommandEnabled( |
| IDC_CLOSE_TAB, |
| web_app::IsTabClosable(browser_->tab_strip_model(), tab_index)); |
| command_updater_.UpdateCommandEnabled(IDC_WINDOW_CLOSE_TABS_TO_RIGHT, |
| CanCloseTabsToRight(browser_)); |
| command_updater_.UpdateCommandEnabled(IDC_WINDOW_CLOSE_OTHER_TABS, |
| CanCloseOtherTabs(browser_)); |
| command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_TO_NEW_WINDOW, |
| CanMoveActiveTabToNewWindow(browser_)); |
| UpdateCommandsForBookmarkEditing(); |
| } |
| |
| actions::ActionItem* BrowserCommandController::FindAction( |
| actions::ActionId action_id) { |
| BrowserActions* browser_actions = browser_->browser_actions(); |
| |
| // If there is no root action item then ActionManager falls back to the |
| // root_action_parent_ which might contain actions from other browser windows. |
| if (!browser_actions->root_action_item()) { |
| return nullptr; |
| } |
| |
| return actions::ActionManager::Get().FindAction( |
| action_id, browser_actions->root_action_item()); |
| } |
| |
| void BrowserCommandController::UpdateCommandAndActionEnabled( |
| int command_id, |
| actions::ActionId action_id, |
| bool enabled) { |
| command_updater_.UpdateCommandEnabled(command_id, enabled); |
| if (auto* const action = FindAction(action_id)) { |
| action->SetEnabled(enabled); |
| } |
| } |
| |
| void BrowserCommandController::UpdateCommandsForEnableGlicChanged() { |
| #if BUILDFLAG(ENABLE_GLIC) |
| command_updater_.UpdateCommandEnabled( |
| IDC_OPEN_GLIC, glic::GlicEnabling::IsEnabledForProfile(profile())); |
| #endif // BUILDFLAG(ENABLE_GLIC) |
| } |
| |
| BrowserWindow* BrowserCommandController::window() { |
| return browser_->window(); |
| } |
| |
| Profile* BrowserCommandController::profile() { |
| return browser_->profile(); |
| } |
| |
| } // namespace chrome |