From 0fd4f929b7d13ad33dfbf9fa60c62a2c0e210155 Mon Sep 17 00:00:00 2001 From: Simon Hong Date: Tue, 7 Sep 2021 20:29:15 +0900 Subject: [PATCH] Added brave vpn toggle item to app menu with patching Need to find another way w/o patching or reducing patch files. --- app/brave_command_ids.h | 1 + .../ui/brave_browser_command_controller.cc | 3 ++ ..._browser_command_controller_browsertest.cc | 2 ++ browser/ui/toolbar/brave_app_menu_model.cc | 1 - browser/ui/toolbar/brave_vpn_menu_model.cc | 25 ++++++++++++-- browser/ui/toolbar/brave_vpn_menu_model.h | 5 +++ ...browser-ui-views-toolbar-app_menu.cc.patch | 18 ++++++++++ ...-browser-ui-views-toolbar-app_menu.h.patch | 12 +++++++ patches/ui-base-models-menu_model.h.patch | 12 +++++++ .../ui-base-models-simple_menu_model.cc.patch | 15 +++++++++ .../ui-base-models-simple_menu_model.h.patch | 12 +++++++ ...views-controls-menu-menu_delegate.cc.patch | 13 ++++++++ ...-views-controls-menu-menu_delegate.h.patch | 13 ++++++++ ...iews-controls-menu-menu_item_view.cc.patch | 33 +++++++++++++++++++ ...views-controls-menu-menu_item_view.h.patch | 12 +++++++ ...-controls-menu-menu_model_adapter.cc.patch | 14 ++++++++ 16 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 patches/chrome-browser-ui-views-toolbar-app_menu.cc.patch create mode 100644 patches/chrome-browser-ui-views-toolbar-app_menu.h.patch create mode 100644 patches/ui-base-models-menu_model.h.patch create mode 100644 patches/ui-base-models-simple_menu_model.cc.patch create mode 100644 patches/ui-base-models-simple_menu_model.h.patch create mode 100644 patches/ui-views-controls-menu-menu_delegate.cc.patch create mode 100644 patches/ui-views-controls-menu-menu_delegate.h.patch create mode 100644 patches/ui-views-controls-menu-menu_item_view.cc.patch create mode 100644 patches/ui-views-controls-menu-menu_item_view.h.patch create mode 100644 patches/ui-views-controls-menu-menu_model_adapter.cc.patch diff --git a/app/brave_command_ids.h b/app/brave_command_ids.h index 423430ecaca..945a56d0b1e 100644 --- a/app/brave_command_ids.h +++ b/app/brave_command_ids.h @@ -44,6 +44,7 @@ #define IDC_SEND_BRAVE_VPN_FEEDBACK 56031 #define IDC_ABOUT_BRAVE_VPN 56032 #define IDC_MANAGE_BRAVE_VPN_PLAN 56033 +#define IDC_TOGGLE_BRAVE_VPN 56034 #define IDC_CONTENT_CONTEXT_IMPORT_IPNS_KEYS_START 56100 #define IDC_CONTENT_CONTEXT_IMPORT_IPNS_KEYS_END 56199 diff --git a/browser/ui/brave_browser_command_controller.cc b/browser/ui/brave_browser_command_controller.cc index 23d6e6e93a8..d48634b4640 100644 --- a/browser/ui/brave_browser_command_controller.cc +++ b/browser/ui/brave_browser_command_controller.cc @@ -196,6 +196,7 @@ void BraveBrowserCommandController::UpdateCommandForBraveVPN() { UpdateCommandEnabled(IDC_SEND_BRAVE_VPN_FEEDBACK, false); UpdateCommandEnabled(IDC_ABOUT_BRAVE_VPN, false); UpdateCommandEnabled(IDC_MANAGE_BRAVE_VPN_PLAN, false); + UpdateCommandEnabled(IDC_TOGGLE_BRAVE_VPN, false); return; } @@ -209,6 +210,7 @@ void BraveBrowserCommandController::UpdateCommandForBraveVPN() { BraveVpnServiceFactory::GetForProfile(browser_->profile()); // Only show vpn sub menu for purchased user. UpdateCommandEnabled(IDC_BRAVE_VPN_MENU, vpn_service->is_purchased_user()); + UpdateCommandEnabled(IDC_TOGGLE_BRAVE_VPN, vpn_service->is_purchased_user()); #endif } @@ -292,6 +294,7 @@ bool BraveBrowserCommandController::ExecuteBraveCommandWithDisposition( case IDC_SEND_BRAVE_VPN_FEEDBACK: case IDC_ABOUT_BRAVE_VPN: case IDC_MANAGE_BRAVE_VPN_PLAN: + case IDC_TOGGLE_BRAVE_VPN: NOTIMPLEMENTED(); break; default: diff --git a/browser/ui/brave_browser_command_controller_browsertest.cc b/browser/ui/brave_browser_command_controller_browsertest.cc index 39bacc1a6ea..bca0607090a 100644 --- a/browser/ui/brave_browser_command_controller_browsertest.cc +++ b/browser/ui/brave_browser_command_controller_browsertest.cc @@ -68,6 +68,7 @@ class BraveBrowserCommandControllerTest : public InProcessBrowserTest { command_controller->IsCommandEnabled(IDC_MANAGE_BRAVE_VPN_PLAN)); EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_BRAVE_VPN_MENU)); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_TOGGLE_BRAVE_VPN)); SetPurchasedUserForBraveVPN(browser, true); EXPECT_TRUE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_VPN_PANEL)); @@ -80,6 +81,7 @@ class BraveBrowserCommandControllerTest : public InProcessBrowserTest { command_controller->IsCommandEnabled(IDC_MANAGE_BRAVE_VPN_PLAN)); EXPECT_TRUE(command_controller->IsCommandEnabled(IDC_BRAVE_VPN_MENU)); + EXPECT_TRUE(command_controller->IsCommandEnabled(IDC_TOGGLE_BRAVE_VPN)); } base::test::ScopedFeatureList scoped_feature_list_; diff --git a/browser/ui/toolbar/brave_app_menu_model.cc b/browser/ui/toolbar/brave_app_menu_model.cc index 18b44b50177..502c3207fee 100644 --- a/browser/ui/toolbar/brave_app_menu_model.cc +++ b/browser/ui/toolbar/brave_app_menu_model.cc @@ -238,7 +238,6 @@ void BraveAppMenuModel::InsertBraveMenuItems() { const bool show_panel_item = IsCommandIdEnabled(IDC_SHOW_BRAVE_VPN_PANEL); if (show_menu_item) { - // Sub menu for post-purchased is not yet implemented. sub_menus_.push_back(std::make_unique(browser())); InsertSubMenuWithStringIdAt(GetIndexOfBraveVPNItem(), IDC_BRAVE_VPN_MENU, IDS_BRAVE_VPN_MENU, sub_menus_.back().get()); diff --git a/browser/ui/toolbar/brave_vpn_menu_model.cc b/browser/ui/toolbar/brave_vpn_menu_model.cc index 87dc1e94720..2d9b1debf20 100644 --- a/browser/ui/toolbar/brave_vpn_menu_model.cc +++ b/browser/ui/toolbar/brave_vpn_menu_model.cc @@ -18,8 +18,8 @@ BraveVPNMenuModel::BraveVPNMenuModel(Browser* browser) BraveVPNMenuModel::~BraveVPNMenuModel() = default; void BraveVPNMenuModel::Build() { - DCHECK(browser_); - + AddToggleItemWithStringId(IDC_TOGGLE_BRAVE_VPN, IDS_BRAVE_VPN_MENU); + AddSeparator(ui::NORMAL_SEPARATOR); AddItemWithStringId(IDC_TOGGLE_BRAVE_VPN_TOOLBAR_BUTTON, IDS_BRAVE_VPN_SHOW_VPN_BUTTON_MENU_ITEM); AddItemWithStringId(IDC_SEND_BRAVE_VPN_FEEDBACK, @@ -29,6 +29,27 @@ void BraveVPNMenuModel::Build() { IDS_BRAVE_VPN_MANAGE_MY_PLAN_MENU_ITEM); } +bool BraveVPNMenuModel::IsItemCheckedAt(int index) const { + ui::MenuModel::ItemType item_type = GetTypeAt(index); + if (item_type == ui::MenuModel::TYPE_TOGGLE) { + return IsCommandIdChecked(GetCommandIdAt(index)); + } + + return SimpleMenuModel::IsItemCheckedAt(index); +} + void BraveVPNMenuModel::ExecuteCommand(int command_id, int event_flags) { chrome::ExecuteCommand(browser_, command_id); } + +bool BraveVPNMenuModel::IsCommandIdChecked(int command_id) const { + if (command_id != IDC_TOGGLE_BRAVE_VPN) + return false; + + return IsVPNConnected(); +} + +bool BraveVPNMenuModel::IsVPNConnected() const { + NOTIMPLEMENTED(); + return true; +} diff --git a/browser/ui/toolbar/brave_vpn_menu_model.h b/browser/ui/toolbar/brave_vpn_menu_model.h index 844c75bcd08..828234f01f2 100644 --- a/browser/ui/toolbar/brave_vpn_menu_model.h +++ b/browser/ui/toolbar/brave_vpn_menu_model.h @@ -20,10 +20,15 @@ class BraveVPNMenuModel : public ui::SimpleMenuModel, BraveVPNMenuModel& operator=(const BraveVPNMenuModel&) = delete; private: + // ui::SimpleMenuModel override: + bool IsItemCheckedAt(int index) const override; + // ui::SimpleMenuModel::Delegate override: void ExecuteCommand(int command_id, int event_flags) override; + bool IsCommandIdChecked(int command_id) const override; void Build(); + bool IsVPNConnected() const; Browser* browser_ = nullptr; }; diff --git a/patches/chrome-browser-ui-views-toolbar-app_menu.cc.patch b/patches/chrome-browser-ui-views-toolbar-app_menu.cc.patch new file mode 100644 index 00000000000..ecbcfffe9ed --- /dev/null +++ b/patches/chrome-browser-ui-views-toolbar-app_menu.cc.patch @@ -0,0 +1,18 @@ +diff --git a/chrome/browser/ui/views/toolbar/app_menu.cc b/chrome/browser/ui/views/toolbar/app_menu.cc +index ad830a7da7dd77139dd5b19c602b7f802174fdff..d44fc0574032825b66dca95455fea29d6ecf189e 100644 +--- a/chrome/browser/ui/views/toolbar/app_menu.cc ++++ b/chrome/browser/ui/views/toolbar/app_menu.cc +@@ -1087,6 +1087,13 @@ bool AppMenu::ShouldExecuteCommandWithoutClosingMenu(int command_id, + command_id, event)); + } + ++base::RepeatingCallback AppMenu::GetToggleMenuCallback(int command_id) const { ++ return base::BindRepeating([](Browser* browser, const ui::Event& event) { ++ chrome::ExecuteCommand(browser, IDC_TOGGLE_BRAVE_VPN); ++ }, ++ browser_); ++} ++ + void AppMenu::BookmarkModelChanged() { + DCHECK(bookmark_menu_delegate_.get()); + if (!bookmark_menu_delegate_->is_mutating_model()) diff --git a/patches/chrome-browser-ui-views-toolbar-app_menu.h.patch b/patches/chrome-browser-ui-views-toolbar-app_menu.h.patch new file mode 100644 index 00000000000..5c30a07b78e --- /dev/null +++ b/patches/chrome-browser-ui-views-toolbar-app_menu.h.patch @@ -0,0 +1,12 @@ +diff --git a/chrome/browser/ui/views/toolbar/app_menu.h b/chrome/browser/ui/views/toolbar/app_menu.h +index 494e0ba95614c0f5894db2c3619ffda29cea79a9..7cea0f42a7b4f7f9b62cbabc52a12cca480fba50 100644 +--- a/chrome/browser/ui/views/toolbar/app_menu.h ++++ b/chrome/browser/ui/views/toolbar/app_menu.h +@@ -94,6 +94,7 @@ class AppMenu : public views::MenuDelegate, + void OnMenuClosed(views::MenuItemView* menu) override; + bool ShouldExecuteCommandWithoutClosingMenu(int command_id, + const ui::Event& event) override; ++ base::RepeatingCallback GetToggleMenuCallback(int command_id) const override; + + // bookmarks::BaseBookmarkModelObserver overrides: + void BookmarkModelChanged() override; diff --git a/patches/ui-base-models-menu_model.h.patch b/patches/ui-base-models-menu_model.h.patch new file mode 100644 index 00000000000..755c802ab86 --- /dev/null +++ b/patches/ui-base-models-menu_model.h.patch @@ -0,0 +1,12 @@ +diff --git a/ui/base/models/menu_model.h b/ui/base/models/menu_model.h +index 279be87a33e9ea11020b7f1ce823866907388bb5..756f7ac34bff2ddf4561fdac58e3628d6890e936 100644 +--- a/ui/base/models/menu_model.h ++++ b/ui/base/models/menu_model.h +@@ -42,6 +42,7 @@ class COMPONENT_EXPORT(UI_BASE) MenuModel + // background matches the menu's rounded corners. + TYPE_TITLE, // Plain text that does not perform any action when + // selected. ++ TYPE_TOGGLE, + }; + + MenuModel(); diff --git a/patches/ui-base-models-simple_menu_model.cc.patch b/patches/ui-base-models-simple_menu_model.cc.patch new file mode 100644 index 00000000000..2a48d427be9 --- /dev/null +++ b/patches/ui-base-models-simple_menu_model.cc.patch @@ -0,0 +1,15 @@ +diff --git a/ui/base/models/simple_menu_model.cc b/ui/base/models/simple_menu_model.cc +index e7504cd790821ffa213961b51c0c9ab7763ddd82..db6b5d7331f7e4ef7bf2d4672c5d96a671fdc77f 100644 +--- a/ui/base/models/simple_menu_model.cc ++++ b/ui/base/models/simple_menu_model.cc +@@ -145,6 +145,10 @@ void SimpleMenuModel::AddTitle(const std::u16string& label) { + AppendItem(std::move(title_item)); + } + ++void SimpleMenuModel::AddToggleItemWithStringId(int command_id, int string_id) { ++ AppendItem(Item(command_id, TYPE_TOGGLE, l10n_util::GetStringUTF16(string_id))); ++} ++ + void SimpleMenuModel::AddSeparator(MenuSeparatorType separator_type) { + if (items_.empty()) { + if (separator_type == NORMAL_SEPARATOR) { diff --git a/patches/ui-base-models-simple_menu_model.h.patch b/patches/ui-base-models-simple_menu_model.h.patch new file mode 100644 index 00000000000..25dfb221c16 --- /dev/null +++ b/patches/ui-base-models-simple_menu_model.h.patch @@ -0,0 +1,12 @@ +diff --git a/ui/base/models/simple_menu_model.h b/ui/base/models/simple_menu_model.h +index 4536b388717844cc74905760828e80ea6d64b7b1..25a3b5ff740b690eff93362d45b18f6eee0c98c5 100644 +--- a/ui/base/models/simple_menu_model.h ++++ b/ui/base/models/simple_menu_model.h +@@ -96,6 +96,7 @@ class COMPONENT_EXPORT(UI_BASE) SimpleMenuModel : public MenuModel { + const std::u16string& label, + const ui::ImageModel& icon); + void AddTitle(const std::u16string& label); ++ void AddToggleItemWithStringId(int command_id, int string_id); + + // Adds a separator of the specified type to the model. + // - Adding a separator after another separator is always invalid if they diff --git a/patches/ui-views-controls-menu-menu_delegate.cc.patch b/patches/ui-views-controls-menu-menu_delegate.cc.patch new file mode 100644 index 00000000000..7dd586b55d8 --- /dev/null +++ b/patches/ui-views-controls-menu-menu_delegate.cc.patch @@ -0,0 +1,13 @@ +diff --git a/ui/views/controls/menu/menu_delegate.cc b/ui/views/controls/menu/menu_delegate.cc +index 470a8896ce43d0613b34cf2da943653713ad6634..7e703848ec6dcd9f996d55c0b63038d1c5b58442 100644 +--- a/ui/views/controls/menu/menu_delegate.cc ++++ b/ui/views/controls/menu/menu_delegate.cc +@@ -156,4 +156,8 @@ bool MenuDelegate::ShouldTryPositioningBesideAnchor() const { + return true; + } + ++base::RepeatingCallback MenuDelegate::GetToggleMenuCallback(int command_id) const { ++ return base::NullCallback(); ++} ++ + } // namespace views diff --git a/patches/ui-views-controls-menu-menu_delegate.h.patch b/patches/ui-views-controls-menu-menu_delegate.h.patch new file mode 100644 index 00000000000..95dbf783b17 --- /dev/null +++ b/patches/ui-views-controls-menu-menu_delegate.h.patch @@ -0,0 +1,13 @@ +diff --git a/ui/views/controls/menu/menu_delegate.h b/ui/views/controls/menu/menu_delegate.h +index b47a61998daaa3fabfbd58f7b0454fcaaa9f0dcf..e0a4155f8227465b3ecb4f8abdace2af2e4d6420 100644 +--- a/ui/views/controls/menu/menu_delegate.h ++++ b/ui/views/controls/menu/menu_delegate.h +@@ -231,6 +231,8 @@ class VIEWS_EXPORT MenuDelegate { + // rather than directly above or below it, when the menu is too tall to fit + // within the screen. + virtual bool ShouldTryPositioningBesideAnchor() const; ++ ++ virtual base::RepeatingCallback GetToggleMenuCallback(int command_id) const; + }; + + } // namespace views diff --git a/patches/ui-views-controls-menu-menu_item_view.cc.patch b/patches/ui-views-controls-menu-menu_item_view.cc.patch new file mode 100644 index 00000000000..d6a76a9f978 --- /dev/null +++ b/patches/ui-views-controls-menu-menu_item_view.cc.patch @@ -0,0 +1,33 @@ +diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc +index 039cbc90f0eed01ecdda3c27a9aa56cc0b6ef3ac..5fd42621b9c56fbe692222ff60d35b137ce46c11 100644 +--- a/ui/views/controls/menu/menu_item_view.cc ++++ b/ui/views/controls/menu/menu_item_view.cc +@@ -52,6 +52,8 @@ + #include "ui/views/view_class_properties.h" + #include "ui/views/widget/widget.h" + ++#include "ui/views/controls/button/toggle_button.h" ++ + #if defined(OS_MAC) + #include "ui/views/accessibility/view_accessibility.h" + #endif // defined(OS_MAC) +@@ -223,6 +225,7 @@ void MenuItemView::GetAccessibleNodeData(ui::AXNodeData* node_data) { + node_data->SetHasPopup(ax::mojom::HasPopup::kMenu); + break; + case Type::kCheckbox: ++ case Type::kToggle: + case Type::kRadio: { + const bool is_checked = + GetDelegate() && GetDelegate()->IsItemChecked(GetCommand()); +@@ -861,6 +864,11 @@ void MenuItemView::Init(MenuItemView* parent, + radio_check_image_view_->SetCanProcessEventsWithinSubtree(false); + } + ++ if (type_ == Type::kToggle && GetDelegate()) { ++ auto* toggle = AddChildView(std::make_unique(GetDelegate()->GetToggleMenuCallback(GetCommand()))); ++ toggle->SetIsOn(GetDelegate()->IsItemChecked(GetCommand())); ++ } ++ + if (type_ == Type::kActionableSubMenu) + vertical_separator_ = AddChildView(std::make_unique()); + diff --git a/patches/ui-views-controls-menu-menu_item_view.h.patch b/patches/ui-views-controls-menu-menu_item_view.h.patch new file mode 100644 index 00000000000..ba4461e43aa --- /dev/null +++ b/patches/ui-views-controls-menu-menu_item_view.h.patch @@ -0,0 +1,12 @@ +diff --git a/ui/views/controls/menu/menu_item_view.h b/ui/views/controls/menu/menu_item_view.h +index 224401e3eb4e6548de049df68f3dbd873ddc73da..06c271885716e904df9b92f9060180f9a18e9573 100644 +--- a/ui/views/controls/menu/menu_item_view.h ++++ b/ui/views/controls/menu/menu_item_view.h +@@ -92,6 +92,7 @@ class VIEWS_EXPORT MenuItemView : public View { + kTitle, // Title text, does not perform any action. + kEmpty, // kEmpty is a special type for empty menus that is + // only used internally. ++ kToggle, + }; + + // Where the menu should be drawn, above or below the bounds (when diff --git a/patches/ui-views-controls-menu-menu_model_adapter.cc.patch b/patches/ui-views-controls-menu-menu_model_adapter.cc.patch new file mode 100644 index 00000000000..ca8b4f599c1 --- /dev/null +++ b/patches/ui-views-controls-menu-menu_model_adapter.cc.patch @@ -0,0 +1,14 @@ +diff --git a/ui/views/controls/menu/menu_model_adapter.cc b/ui/views/controls/menu/menu_model_adapter.cc +index 895745cf0f7e55af19cdf2c27dfd6c0fa8dd9ba1..76e55c966fe91bcc02fbbf770ed0d88e9b12e3ed 100644 +--- a/ui/views/controls/menu/menu_model_adapter.cc ++++ b/ui/views/controls/menu/menu_model_adapter.cc +@@ -100,6 +100,9 @@ MenuItemView* MenuModelAdapter::AddMenuItemFromModelAt(ui::MenuModel* model, + case ui::MenuModel::TYPE_HIGHLIGHTED: + type = MenuItemView::Type::kHighlighted; + break; ++ case ui::MenuModel::TYPE_TOGGLE: ++ type = MenuItemView::Type::kToggle; ++ break; + } + + if (*type == MenuItemView::Type::kSeparator) {