chromium/chrome/browser/ui/views/toolbar/app_menu.cc

// Copyright 2013 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/views/toolbar/app_menu.h"

#include <stdint.h>

#include <algorithm>
#include <cmath>
#include <memory>
#include <optional>
#include <set>
#include <utility>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/i18n/number_formatting.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/not_fatal_until.h"
#include "base/strings/utf_string_conversions.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/sharing_hub/sharing_hub_features.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/signin_util.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/ui/bookmarks/bookmark_stats.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/global_error/global_error_service_factory.h"
#include "chrome/browser/ui/hats/trust_safety_sentiment_service_factory.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/profiles/profile_view_utils.h"
#include "chrome/browser/ui/safety_hub/safety_hub_hats_service.h"
#include "chrome/browser/ui/safety_hub/safety_hub_hats_service_factory.h"
#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/toolbar/app_menu_model.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/frame/app_menu_button.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/toolbar_button_provider.h"
#include "chrome/browser/upgrade_detector/upgrade_detector.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/saved_tab_groups/features.h"
#include "components/signin/public/base/signin_pref_names.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/zoom/page_zoom.h"
#include "components/zoom/zoom_controller.h"
#include "components/zoom/zoom_event_manager.h"
#include "content/public/browser/host_zoom_map.h"
#include "content/public/browser/web_contents.h"
#include "extensions/common/feature_switch.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/accelerators/menu_label_accelerator_util.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/models/image_model.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/themed_vector_icon.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/window_open_disposition_utils.h"
#include "ui/color/color_id.h"
#include "ui/color/color_provider.h"
#include "ui/compositor/layer_tree_owner.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/scoped_canvas.h"
#include "ui/gfx/text_elider.h"
#include "ui/gfx/text_utils.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/menu/menu_config.h"
#include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/controls/menu/menu_model_adapter.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/menu/menu_scroll_view_container.h"
#include "ui/views/controls/menu/submenu_view.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/style/typography.h"
#include "ui/views/style/typography_provider.h"
#include "ui/views/view_class_properties.h"
#include "ui/views/view_utils.h"
#include "ui/views/widget/widget.h"

UserMetricsAction;
BookmarkModel;
WebContents;
ButtonMenuItemModel;
MenuModel;
Button;
ImageButton;
Label;
LabelButton;
MenuConfig;
MenuItemView;
View;

namespace {

// Horizontal padding on the edges of the in-menu buttons.
const int kHorizontalPadding =;

constexpr int kBookmarksCommandIdOffset =;
constexpr int kRecentTabsCommandIdOffset =;
constexpr int kTabGroupsCommandIdOffset =;

#if BUILDFLAG(IS_CHROMEOS)
// Extra horizontal space to reserve for the fullscreen button.
const int kFullscreenPadding = 74;
// Padding to left and right of the XX% label.
const int kZoomLabelHorizontalPadding = kHorizontalPadding;
#else
const int kFullscreenPadding =;
const int kZoomLabelHorizontalPadding =;
#endif

// Returns true if |command_id| identifies a bookmark menu item.
bool IsBookmarkCommand(int command_id) {}

// Returns true if |command_id| identifies a recent tabs menu item.
bool IsRecentTabsCommand(int command_id) {}

// Returns true if |command_id| identifies a tab group menu item.
bool IsTabGroupsCommand(int command_id) {}

// Combination border/background for the buttons contained in the menu. The
// painting of the border/background is done here as LabelButton does not always
// paint the border.
class InMenuButtonBackground : public views::Background {};

std::u16string GetAccessibleNameForAppMenuItem(ButtonMenuItemModel* model,
                                               size_t item_index,
                                               int accessible_string_id,
                                               bool add_accelerator_text) {}

// A button that lives inside a menu item.
class InMenuButton : public LabelButton {};

BEGIN_METADATA()

// A button with an image inside a menu item.
class InMenuImageButton : public ImageButton {};

BEGIN_METADATA()

// Conditionally return the update app menu item substring text based on upgrade
// detector state.
std::u16string GetUpgradeDialogSubstringText() {}

std::u16string GetSigninStatusChipString(Profile* profile) {}

// Helper method that adds a bespoke chip to the profile related menu items.
void AddSignedInChipToProfileMenuItem(
    Profile* profile,
    views::MenuItemView* item,
    const int horizontal_padding,
    std::vector<base::CallbackListSubscription>&
        profile_menu_subscription_list) {}

// AppMenuView is a view that can contain label buttons.
class AppMenuView : public views::View {};

BEGIN_METADATA()

// Subclass of ImageButton whose preferred size includes the size of the border.
class FullscreenButton : public ImageButton {};

BEGIN_METADATA()

}  // namespace

// CutCopyPasteView ------------------------------------------------------------

// CutCopyPasteView is the view containing the cut/copy/paste buttons.
class AppMenu::CutCopyPasteView : public AppMenuView {};

BEGIN_METADATA()

// ZoomView --------------------------------------------------------------------

// ZoomView contains the various zoom controls: two buttons to increase/decrease
// the zoom, a label showing the current zoom percent, and a button to go
// full-screen.
class AppMenu::ZoomView : public AppMenuView {};

BEGIN_METADATA()

// RecentTabsMenuModelDelegate  ------------------------------------------------

// Provides the ui::MenuModelDelegate implementation for RecentTabsSubMenuModel
// items.
class AppMenu::RecentTabsMenuModelDelegate : public ui::MenuModelDelegate {};

// AppMenu ------------------------------------------------------------------

AppMenu::AppMenu(Browser* browser, ui::MenuModel* model, int run_types)
    :{}

AppMenu::~AppMenu() {}

void AppMenu::RunMenu(views::MenuButtonController* host) {}

void AppMenu::CloseMenu() {}

bool AppMenu::IsShowing() const {}

const gfx::FontList* AppMenu::GetLabelFontList(int command_id) const {}

std::optional<SkColor> AppMenu::GetLabelColor(int command_id) const {}

std::u16string AppMenu::GetTooltipText(int command_id,
                                       const gfx::Point& p) const {}

bool AppMenu::IsTriggerableEvent(views::MenuItemView* menu,
                                 const ui::Event& e) {}

bool AppMenu::GetDropFormats(MenuItemView* menu,
                             int* formats,
                             std::set<ui::ClipboardFormatType>* format_types) {}

bool AppMenu::AreDropTypesRequired(MenuItemView* menu) {}

bool AppMenu::CanDrop(MenuItemView* menu, const ui::OSExchangeData& data) {}

ui::mojom::DragOperation AppMenu::GetDropOperation(
    MenuItemView* item,
    const ui::DropTargetEvent& event,
    DropPosition* position) {}

views::View::DropCallback AppMenu::GetDropCallback(
    views::MenuItemView* menu,
    DropPosition position,
    const ui::DropTargetEvent& event) {}

bool AppMenu::ShowContextMenu(MenuItemView* source,
                              int command_id,
                              const gfx::Point& p,
                              ui::MenuSourceType source_type) {}

bool AppMenu::CanDrag(MenuItemView* menu) {}

void AppMenu::WriteDragData(MenuItemView* sender, ui::OSExchangeData* data) {}

int AppMenu::GetDragOperations(MenuItemView* sender) {}

int AppMenu::GetMaxWidthForMenu(MenuItemView* menu) {}

bool AppMenu::IsItemChecked(int command_id) const {}

bool AppMenu::IsCommandEnabled(int command_id) const {}

void AppMenu::ExecuteCommand(int command_id, int mouse_event_flags) {}

bool AppMenu::GetAccelerator(int command_id,
                             ui::Accelerator* accelerator) const {}

void AppMenu::WillShowMenu(MenuItemView* menu) {}

void AppMenu::WillHideMenu(MenuItemView* menu) {}

bool AppMenu::ShouldCloseOnDragComplete() {}

void AppMenu::OnMenuClosed(views::MenuItemView* menu) {}

bool AppMenu::ShouldExecuteCommandWithoutClosingMenu(int command_id,
                                                     const ui::Event& event) {}

void AppMenu::BookmarkModelChanged() {}

void AppMenu::OnGlobalErrorsChanged() {}

views::View* AppMenu::GetZoomAppMenuViewForTest() {}

void AppMenu::PopulateMenu(MenuItemView* parent, MenuModel* model) {}

MenuItemView* AppMenu::AddMenuItem(MenuItemView* parent,
                                   size_t menu_index,
                                   MenuModel* model,
                                   size_t model_index,
                                   MenuModel::ItemType menu_type) {}

void AppMenu::CancelAndEvaluate(ButtonMenuItemModel* model, size_t index) {}

void AppMenu::CreateBookmarkMenu() {}

size_t AppMenu::ModelIndexFromCommandId(int command_id) const {}

void AppMenu::SetTimerForTesting(base::ElapsedTimer timer) {}