From 0a9523833f7256e4fe6992e8d0291c26367073cf Mon Sep 17 00:00:00 2001 From: Simon Hong Date: Fri, 30 Aug 2024 22:39:33 +0900 Subject: [PATCH] Added search promotion button in omnibox fix https://github.com/brave/brave-browser/issues/40776 --- app/brave_generated_resources.grd | 7 + app/theme/brave_theme_resources.grd | 2 + ...ch_conversion_button_brave_search_icon.png | Bin 0 -> 793 bytes ...rave_search_conversion_button_ddg_icon.png | Bin 0 -> 834 bytes ...ch_conversion_button_brave_search_icon.png | Bin 0 -> 1764 bytes ...rave_search_conversion_button_ddg_icon.png | Bin 0 -> 1822 bytes browser/ui/BUILD.gn | 2 + browser/ui/color/brave_color_id.h | 11 +- browser/ui/color/brave_color_mixer.cc | 21 +++ .../location_bar/brave_location_bar_view.cc | 32 ++++ .../location_bar/brave_location_bar_view.h | 7 +- ...search_conversion_promotion_button_view.cc | 159 ++++++++++++++++++ ..._search_conversion_promotion_button_view.h | 42 +++++ .../views/location_bar/location_bar_view.cc | 18 ++ .../ui/views/location_bar/location_bar_view.h | 2 + .../brave_search_conversion/features.cc | 4 + components/brave_search_conversion/features.h | 1 + components/vector_icons/BUILD.gn | 2 + ...ws-location_bar-location_bar_view.cc.patch | 14 +- 19 files changed, 319 insertions(+), 5 deletions(-) create mode 100644 app/theme/default_100_percent/brave/brave_search_conversion_button_brave_search_icon.png create mode 100644 app/theme/default_100_percent/brave/brave_search_conversion_button_ddg_icon.png create mode 100644 app/theme/default_200_percent/brave/brave_search_conversion_button_brave_search_icon.png create mode 100644 app/theme/default_200_percent/brave/brave_search_conversion_button_ddg_icon.png create mode 100644 browser/ui/views/location_bar/brave_search_conversion_promotion_button_view.cc create mode 100644 browser/ui/views/location_bar/brave_search_conversion_promotion_button_view.h diff --git a/app/brave_generated_resources.grd b/app/brave_generated_resources.grd index 3d5ae0891386..b896bc689d7e 100644 --- a/app/brave_generated_resources.grd +++ b/app/brave_generated_resources.grd @@ -578,6 +578,13 @@ Or change later at $2brave://settings/ext Dismiss Brave search conversion, press Enter to remove this suggestion + + Try Brave Search + + + Switch to Brave Search + + Help improve $1Brave Search by sending anonymous usage data. $2More info diff --git a/app/theme/brave_theme_resources.grd b/app/theme/brave_theme_resources.grd index 11ac016ddfe5..50ae75d0505a 100644 --- a/app/theme/brave_theme_resources.grd +++ b/app/theme/brave_theme_resources.grd @@ -105,6 +105,8 @@ + + diff --git a/app/theme/default_100_percent/brave/brave_search_conversion_button_brave_search_icon.png b/app/theme/default_100_percent/brave/brave_search_conversion_button_brave_search_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..63b0667d2ea29b2fee2cf096bae33d30582751f2 GIT binary patch literal 793 zcmV+!1LpjRP)9e%5)}ouL_vieQcwh88zn*!f;c^3hd&TsK?yN5 zp+UNcB0@?OM+gvAP6P>J``$9|&RD=nr+0qdot>SX75w)U=Bqg|{TYav7R9)`Qy>s% zV2xL6E>}B$$ICFWTuqzfT7ha=Rog1kg0=fh4`I9v0cHe}gJ|7$4{ObOJsbkW$;a#l zE2Y&&#m4SZfS*`F-vC_({IVf>s1+~WBRjLgn^1e-^A5x~09V;1UkJBn8=Z$42CtKM zfouwZEwD_9zZ;F0i`jFZw`Z9`wj-68LE&z7+*rG3ZIo|xmTn+o; zTfir_{=BX@f?vG4uxgCAVXes515tAX+wM0@oh6z@k%qH&^F~3m9o0SCUEbl}zZZ4dV&q_ft>(2pyjziam8C(uw%bJ_3S=__jBS&6eQD0r1vWoJtGcx82Y~*+E>yh{-yGr8HtM z22Qm)trO}rK|Zu|IKj%5^~5XJr<6iE&jf#rr-ErJ8W=^?at?DAPK0!VGIo=c@8p5o zd8dKIcLvRY-D6i;BemFx#rgYnAq#6v-g#ZG&9{*{J_`CT%<1T+;bo($~$x%OJi&!(OcK7r@=qVB%ZC3Ny(YSKw6PC zTk!g6PtBMeEE6lQx?Y%Aayu~u7y^-^M7GM$49RB)>)hetbJ1GPg@ySAE|u5dhPHnL X{7*Ml$$Wnf00000NkvXXu0mjfm26p= literal 0 HcmV?d00001 diff --git a/app/theme/default_100_percent/brave/brave_search_conversion_button_ddg_icon.png b/app/theme/default_100_percent/brave/brave_search_conversion_button_ddg_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..70bd99861bb710c6b7d99ade5ccf53ef5d78027f GIT binary patch literal 834 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 M07*qoM6N<$f~&t@r~m)} literal 0 HcmV?d00001 diff --git a/browser/ui/BUILD.gn b/browser/ui/BUILD.gn index e9208895ff9f..792b234e0428 100644 --- a/browser/ui/BUILD.gn +++ b/browser/ui/BUILD.gn @@ -1082,6 +1082,8 @@ source_set("ui") { "views/frame/vertical_tab_strip_widget_delegate_view.h", "views/location_bar/brave_location_bar_view.cc", "views/location_bar/brave_location_bar_view.h", + "views/location_bar/brave_search_conversion_promotion_button_view.cc", + "views/location_bar/brave_search_conversion_promotion_button_view.h", "views/location_bar/brave_star_view.cc", "views/location_bar/brave_star_view.h", "views/profiles/brave_avatar_toolbar_button.cc", diff --git a/browser/ui/color/brave_color_id.h b/browser/ui/color/brave_color_id.h index 97329bca5ef1..c7be6b88b797 100644 --- a/browser/ui/color/brave_color_id.h +++ b/browser/ui/color/brave_color_id.h @@ -39,7 +39,16 @@ E_CPONLY(kColorSearchConversionBannerTypeBackgroundBorderHovered) \ E_CPONLY(kColorSearchConversionBannerTypeBackgroundGradientFrom) \ E_CPONLY(kColorSearchConversionBannerTypeBackgroundGradientTo) \ - E_CPONLY(kColorSearchConversionBannerTypeDescText) + E_CPONLY(kColorSearchConversionBannerTypeDescText) \ + E_CPONLY(kColorSearchConversionButtonBorder) \ + E_CPONLY(kColorSearchConversionButtonBackground) \ + E_CPONLY(kColorSearchConversionButtonBackgroundHovered) \ + E_CPONLY(kColorSearchConversionButtonText) \ + E_CPONLY(kColorSearchConversionButtonCaratRight) \ + E_CPONLY(kColorSearchConversionButtonCloseButton) \ + E_CPONLY(kColorSearchConversionButtonCloseButtonHovered) \ + E_CPONLY(kColorSearchConversionButtonShadow1) \ + E_CPONLY(kColorSearchConversionButtonShadow2) #define BRAVE_SIDEBAR_COLOR_IDS \ E_CPONLY(kColorSidebarAddBubbleBackground) \ diff --git a/browser/ui/color/brave_color_mixer.cc b/browser/ui/color/brave_color_mixer.cc index cd403ca1fcb6..e7800585ebcf 100644 --- a/browser/ui/color/brave_color_mixer.cc +++ b/browser/ui/color/brave_color_mixer.cc @@ -313,6 +313,26 @@ void AddBraveColorMixerForAllThemes(ui::ColorProvider* provider, mixer[kColorToolbarButtonActivated] = {SkColorSetRGB(0x7C, 0x91, 0xFF)}; mixer[kColorSidebarButtonPressed] = {kColorToolbarButtonActivated}; mixer[kColorToolbarContentAreaSeparator] = {kColorToolbar}; + + // Search conversion button in omnibox. + mixer[kColorSearchConversionButtonText] = {nala::kColorPrimary60}; + mixer[kColorSearchConversionButtonBorder] = {nala::kColorPrimary20}; + mixer[kColorSearchConversionButtonBackground] = {nala::kColorPrimary10}; + mixer[kColorSearchConversionButtonBackgroundHovered] = { + nala::kColorPrimary20}; + mixer[kColorSearchConversionButtonText] = {nala::kColorPrimary60}; + mixer[kColorSearchConversionButtonCloseButton] = { + ui::AlphaBlend({nala::kColorIconInteractive}, + {kColorSearchConversionButtonBackground}, 0.5 * 0xff)}; + mixer[kColorSearchConversionButtonCloseButtonHovered] = { + ui::AlphaBlend({nala::kColorIconInteractive}, + {kColorSearchConversionButtonBackground}, 0.7 * 0xff)}; + mixer[kColorSearchConversionButtonCaratRight] = { + kColorSearchConversionButtonCloseButton}; + mixer[kColorSearchConversionButtonShadow1] = { + SkColorSetA(SK_ColorBLACK, 0.05 * 255)}; + mixer[kColorSearchConversionButtonShadow2] = { + SkColorSetA(SK_ColorBLACK, 0.1 * 255)}; } } // namespace @@ -361,6 +381,7 @@ void AddBraveLightThemeColorMixer(ui::ColorProvider* provider, PickColorContrastingToToolbar(key, mixer, SkColorSetRGB(0x49, 0x50, 0x57), SkColorSetRGB(0xFF, 0xFF, 0xFF))}; mixer[kColorMenuItemSubText] = {SkColorSetRGB(0x86, 0x8E, 0x96)}; + // It's "Themeable/Blue/10" but leo/color.h doesn't have it. mixer[kColorSearchConversionBannerTypeBackground] = { SkColorSetRGB(0xEA, 0xF1, 0xFF)}; diff --git a/browser/ui/views/location_bar/brave_location_bar_view.cc b/browser/ui/views/location_bar/brave_location_bar_view.cc index 149130c6e1d7..84e6531cde24 100644 --- a/browser/ui/views/location_bar/brave_location_bar_view.cc +++ b/browser/ui/views/location_bar/brave_location_bar_view.cc @@ -17,10 +17,13 @@ #include "brave/browser/ui/tabs/features.h" #include "brave/browser/ui/views/brave_actions/brave_actions_container.h" #include "brave/browser/ui/views/brave_news/brave_news_action_icon_view.h" +#include "brave/browser/ui/views/location_bar/brave_search_conversion_promotion_button_view.h" #include "brave/browser/ui/views/playlist/playlist_action_icon_view.h" #include "brave/browser/ui/views/toolbar/brave_toolbar_view.h" #include "brave/components/commander/common/buildflags/buildflags.h" #include "brave/components/l10n/common/localization_util.h" +#include "brave/components/omnibox/browser/leo_provider.h" +#include "brave/components/omnibox/browser/promotion_utils.h" #include "brave/grit/brave_theme_resources.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/themes/theme_service_factory.h" @@ -125,6 +128,9 @@ void BraveLocationBarView::Init() { AddChildView(std::make_unique(browser_->profile())); #endif + promotion_button_ = AddChildView( + std::make_unique()); + // brave action buttons brave_actions_ = AddChildView( std::make_unique(browser_, profile())); @@ -189,6 +195,14 @@ void BraveLocationBarView::OnOmniboxBlurred() { LocationBarView::OnOmniboxBlurred(); } +void BraveLocationBarView::Layout(PassKey) { + if (promotion_button_) { + promotion_button_->SetVisible(false); + } + + LayoutSuperclass(this); +} + void BraveLocationBarView::OnChanged() { auto hide_page_actions = ShouldHidePageActionIcons(); if (brave_actions_) { @@ -234,6 +248,24 @@ std::vector BraveLocationBarView::GetLeftMostTrailingViews() { return views; } +bool BraveLocationBarView::ShouldShowSearchPromotionButton() { + if (!promotion_button_) { + return false; + } + + const AutocompleteMatch match = omnibox_view_->model()->CurrentMatch(nullptr); + return AutocompleteMatch::IsSearchType(match.type) && + omnibox_view_->model()->PopupIsOpen() && + !IsBraveSearchPromotionMatch(match) && + !LeoProvider::IsMatchFromLeoProvider(match) && + !GURL(omnibox_view_->GetText()).is_valid() && + !ShouldChipOverrideLocationIcon(); +} + +views::View* BraveLocationBarView::GetSearchPromotionButton() const { + return promotion_button_; +} + void BraveLocationBarView::RefreshBackground() { LocationBarView::RefreshBackground(); diff --git a/browser/ui/views/location_bar/brave_location_bar_view.h b/browser/ui/views/location_bar/brave_location_bar_view.h index ab3fba36b650..02a5d340822b 100644 --- a/browser/ui/views/location_bar/brave_location_bar_view.h +++ b/browser/ui/views/location_bar/brave_location_bar_view.h @@ -19,6 +19,7 @@ class BraveActionsContainer; class BraveActionsContainerTest; +class BraveSearchConversionPromotionButtonView; class PlaylistActionIconView; class RewardsBrowserTest; class SkPath; @@ -70,8 +71,11 @@ class BraveLocationBarView : public LocationBarView { std::vector GetRightMostTrailingViews() override; // Views that locates at left side of upstream's trailing views. std::vector GetLeftMostTrailingViews() override; + bool ShouldShowSearchPromotionButton() override; + views::View* GetSearchPromotionButton() const override; void RefreshBackground() override; void OnOmniboxBlurred() override; + void Layout(PassKey) override; // views::View: gfx::Size CalculatePreferredSize( @@ -80,7 +84,7 @@ class BraveLocationBarView : public LocationBarView { void ChildVisibilityChanged(views::View* child) override; void AddedToWidget() override; int GetBorderRadius() const override; - void FocusLocation(bool is_user_initiated) override; + void FocusLocation(bool is_user_initated) override; SkPath GetFocusRingHighlightPath() const; ContentSettingImageView* GetContentSettingsImageViewForTesting(size_t idx); @@ -113,6 +117,7 @@ class BraveLocationBarView : public LocationBarView { std::unique_ptr shadow_; raw_ptr brave_actions_ = nullptr; raw_ptr brave_news_action_icon_view_ = nullptr; + raw_ptr promotion_button_ = nullptr; #if BUILDFLAG(ENABLE_TOR) raw_ptr onion_location_view_ = nullptr; #endif diff --git a/browser/ui/views/location_bar/brave_search_conversion_promotion_button_view.cc b/browser/ui/views/location_bar/brave_search_conversion_promotion_button_view.cc new file mode 100644 index 000000000000..91a09012be8d --- /dev/null +++ b/browser/ui/views/location_bar/brave_search_conversion_promotion_button_view.cc @@ -0,0 +1,159 @@ +/* Copyright (c) 2024 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/browser/ui/views/location_bar/brave_search_conversion_promotion_button_view.h" + +#include "brave/browser/ui/color/brave_color_id.h" +#include "brave/components/vector_icons/vector_icons.h" +#include "brave/grit/brave_generated_resources.h" +#include "brave/grit/brave_theme_resources.h" +#include "chrome/browser/ui/layout_constants.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/base/models/image_model.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/font_list.h" +#include "ui/views/background.h" +#include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/painter.h" + +using views::BoxLayout; + +BraveSearchConversionPromotionButtonView:: + BraveSearchConversionPromotionButtonView() { + // Hovering on close button should not make this as normal state. + SetNotifyEnterExitOnChild(true); + SetLayoutManager( + std::make_unique(BoxLayout::Orientation::kHorizontal, + gfx::Insets::VH(0, 6), + /*between_child_spacing*/ 4)) + ->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kCenter); + SetTooltipText( + l10n_util::GetStringUTF16(IDS_BRAVE_SEARCH_CONVERSION_BUTTON_TOOLTIP)); + AddChildViews(); + Update(); +} + +BraveSearchConversionPromotionButtonView:: + ~BraveSearchConversionPromotionButtonView() = default; + +void BraveSearchConversionPromotionButtonView::StateChanged( + views::Button::ButtonState old_state) { + Update(); +} + +void BraveSearchConversionPromotionButtonView::OnThemeChanged() { + Button::OnThemeChanged(); + SetupShadow(); + Update(); +} + +float BraveSearchConversionPromotionButtonView::GetCornerRadius() const { + return GetLayoutConstant(LOCATION_BAR_CHILD_CORNER_RADIUS); +} + +void BraveSearchConversionPromotionButtonView::UpdateBackgroundAndBorders() { + auto* cp = GetColorProvider(); + if (!cp) { + return; + } + + const auto bg_color = + cp->GetColor(GetState() == views::Button::STATE_NORMAL + ? kColorSearchConversionButtonBackground + : kColorSearchConversionButtonBackgroundHovered); + const auto stroke_color = cp->GetColor(kColorSearchConversionButtonBorder); + SetBackground(views::CreateBackgroundFromPainter( + views::Painter::CreateRoundRectWith1PxBorderPainter( + bg_color, stroke_color, GetCornerRadius(), SkBlendMode::kSrcOver, + true /* antialias */, true /* should_border_scale */))); +} + +void BraveSearchConversionPromotionButtonView::AddChildViews() { + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + AddChildView(std::make_unique()) + ->SetImage( + *rb.GetImageSkiaNamed(IDR_BRAVE_SEARCH_CONVERSION_BUTTON_DDG_ICON)); + + AddChildView( + std::make_unique(ui::ImageModel::FromVectorIcon( + kLeoCaratLastIcon, kColorSearchConversionButtonCaratRight, 14))); + AddChildView(std::make_unique( + ui::ImageModel::FromImageSkia(*rb.GetImageSkiaNamed( + IDR_BRAVE_SEARCH_CONVERSION_BUTTON_BRAVE_SEARCH_ICON)))); + + auto title_font_list = + views::Label::GetDefaultFontList() + .DeriveWithWeight(gfx::Font::Weight::SEMIBOLD) + .DeriveWithStyle(gfx::Font::NORMAL) + .DeriveWithHeightUpperBound(18) + .DeriveWithSizeDelta( + 12 - views::Label::GetDefaultFontList().GetFontSize()); + views::Label::CustomFont custom_font{title_font_list}; + auto* button_label = AddChildView(std::make_unique( + l10n_util::GetStringUTF16(IDS_BRAVE_SEARCH_CONVERSION_BUTTON_LABEL), + custom_font)); + button_label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); + button_label->SetVerticalAlignment(gfx::VerticalAlignment::ALIGN_MIDDLE); + button_label->SetEnabledColorId(kColorSearchConversionButtonText); + button_label->SetBackgroundColor(SK_ColorTRANSPARENT); + + auto set_image = [](views::ImageButton* close_button, + views::Button::ButtonState state, int color_id) { + close_button->SetImageModel(state, ui::ImageModel::FromVectorIcon( + kLeoCloseCircleIcon, color_id, 16)); + }; + auto* close_button = AddChildView(std::make_unique()); + set_image(close_button, views::Button::STATE_NORMAL, + kColorSearchConversionButtonCloseButton); + set_image(close_button, views::Button::STATE_HOVERED, + kColorSearchConversionButtonCloseButtonHovered); + close_button->SetTooltipText(l10n_util::GetStringUTF16( + IDS_BRAVE_SEARCH_CONVERSION_CLOSE_BUTTON_TOOLTIP)); +} + +void BraveSearchConversionPromotionButtonView::Update() { + UpdateBackgroundAndBorders(); + UpdateShadow(); +} + +void BraveSearchConversionPromotionButtonView::SetupShadow() { + auto* cp = GetColorProvider(); + if (!cp) { + return; + } + + ViewShadow::ShadowParameters shadow_config1{ + .offset_x = 0, + .offset_y = 1, + .blur_radius = 0, + .shadow_color = cp->GetColor(kColorSearchConversionButtonShadow1)}; + + const int radius = GetCornerRadius(); + ViewShadow::ShadowParameters shadow_config2{ + .offset_x = 0, + .offset_y = 1, + .blur_radius = radius, + .shadow_color = cp->GetColor(kColorSearchConversionButtonShadow2)}; + + shadow1_ = std::make_unique(this, radius, shadow_config1); + shadow2_ = std::make_unique(this, radius, shadow_config2); +} + +void BraveSearchConversionPromotionButtonView::UpdateShadow() { + if (!shadow1_ || !shadow2_) { + return; + } + + const bool is_hovered = GetState() == views::Button::STATE_HOVERED; + shadow1_->SetVisible(is_hovered); + shadow2_->SetVisible(is_hovered); +} + +BEGIN_METADATA(BraveSearchConversionPromotionButtonView) +END_METADATA diff --git a/browser/ui/views/location_bar/brave_search_conversion_promotion_button_view.h b/browser/ui/views/location_bar/brave_search_conversion_promotion_button_view.h new file mode 100644 index 000000000000..664f64721eaf --- /dev/null +++ b/browser/ui/views/location_bar/brave_search_conversion_promotion_button_view.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2024 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_BROWSER_UI_VIEWS_LOCATION_BAR_BRAVE_SEARCH_CONVERSION_PROMOTION_BUTTON_VIEW_H_ +#define BRAVE_BROWSER_UI_VIEWS_LOCATION_BAR_BRAVE_SEARCH_CONVERSION_PROMOTION_BUTTON_VIEW_H_ + +#include + +#include "base/memory/raw_ptr.h" +#include "brave/browser/ui/views/view_shadow.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/views/controls/button/button.h" + +class ViewShadow; + +class BraveSearchConversionPromotionButtonView : public views::Button { + METADATA_HEADER(BraveSearchConversionPromotionButtonView, views::Button) + + public: + BraveSearchConversionPromotionButtonView(); + ~BraveSearchConversionPromotionButtonView() override; + + private: + // views::Button overrides: + void StateChanged(views::Button::ButtonState old_state) override; + void OnThemeChanged() override; + + void Update(); + + float GetCornerRadius() const; + void UpdateBackgroundAndBorders(); + void AddChildViews(); + void SetupShadow(); + void UpdateShadow(); + + std::unique_ptr shadow1_; + std::unique_ptr shadow2_; +}; + +#endif // BRAVE_BROWSER_UI_VIEWS_LOCATION_BAR_BRAVE_SEARCH_CONVERSION_PROMOTION_BUTTON_VIEW_H_ diff --git a/chromium_src/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chromium_src/chrome/browser/ui/views/location_bar/location_bar_view.cc index 83b7b6073b55..1ae7f7dbfdfa 100644 --- a/chromium_src/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chromium_src/chrome/browser/ui/views/location_bar/location_bar_view.cc @@ -36,6 +36,15 @@ add_trailing_decoration(item, /*intra_item_padding=*/0); \ } +#define BRAVE_LAYOUT_HANDLE_SEARCH_PROMOTION_BUTTON_VISIBILITY \ + } \ + else if (ShouldShowSearchPromotionButton()) { \ + GetSearchPromotionButton()->SetVisible(true); \ + leading_decorations.AddDecoration(vertical_padding, location_height, \ + false, kLeadingDecorationMaxFraction, \ + /*intra_item_padding=*/0, 0, \ + GetSearchPromotionButton()); + #define OmniboxViewViews BraveOmniboxViewViews #define ChromeOmniboxClient BraveOmniboxClientImpl #define PageActionIconContainerView BravePageActionIconContainerView @@ -52,10 +61,19 @@ #undef PageActionIconContainerView #undef ChromeOmniboxClient #undef OmniboxViewViews +#undef BRAVE_LAYOUT_HANDLE_SEARCH_PROMOTION_BUTTON_VISIBILITY #undef BRAVE_LAYOUT_LEFT_MOST_TRAILING_DECORATIONS #undef BRAVE_LAYOUT_RIGHT_MOST_TRAILING_DECORATIONS #undef BRAVE_LAYOUT_LEADING_DECORATIONS +bool LocationBarView::ShouldShowSearchPromotionButton() { + return false; +} + +views::View* LocationBarView::GetSearchPromotionButton() const { + return nullptr; +} + std::vector LocationBarView::GetRightMostTrailingViews() { return std::vector(); } diff --git a/chromium_src/chrome/browser/ui/views/location_bar/location_bar_view.h b/chromium_src/chrome/browser/ui/views/location_bar/location_bar_view.h index 1264c5b2db2e..7113c602f72b 100644 --- a/chromium_src/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chromium_src/chrome/browser/ui/views/location_bar/location_bar_view.h @@ -11,6 +11,8 @@ friend class BraveLocationBarView; \ \ public: \ + virtual bool ShouldShowSearchPromotionButton(); \ + virtual views::View* GetSearchPromotionButton() const; \ virtual std::vector GetRightMostTrailingViews(); \ virtual std::vector GetLeftMostTrailingViews(); diff --git a/components/brave_search_conversion/features.cc b/components/brave_search_conversion/features.cc index 4505627adb98..b5117684fa0a 100644 --- a/components/brave_search_conversion/features.cc +++ b/components/brave_search_conversion/features.cc @@ -20,6 +20,10 @@ BASE_FEATURE(kOmniboxDDGBanner, "BraveSearchOmniboxDDGBanner", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kOmniboxDDGButton, + "BraveSearchOmniboxDDGButton", + base::FEATURE_DISABLED_BY_DEFAULT); + // Brave search promotion at NTP. BASE_FEATURE(kNTP, "BraveSearchNTP", base::FEATURE_DISABLED_BY_DEFAULT); diff --git a/components/brave_search_conversion/features.h b/components/brave_search_conversion/features.h index 75ace97c0ef6..0dc315d84553 100644 --- a/components/brave_search_conversion/features.h +++ b/components/brave_search_conversion/features.h @@ -20,6 +20,7 @@ BASE_DECLARE_FEATURE(kOmniboxBanner); extern const base::FeatureParam kBannerType; BASE_DECLARE_FEATURE(kOmniboxDDGBanner); +BASE_DECLARE_FEATURE(kOmniboxDDGButton); BASE_DECLARE_FEATURE(kNTP); diff --git a/components/vector_icons/BUILD.gn b/components/vector_icons/BUILD.gn index 7d8a7b945e29..48f81788b8c4 100644 --- a/components/vector_icons/BUILD.gn +++ b/components/vector_icons/BUILD.gn @@ -27,12 +27,14 @@ aggregate_vector_icons("brave_components_vector_icons") { "leo_browser_extensions_remove.icon", "leo_browser_sidebar_right.icon", "leo_browser_split_view_unsplit.icon", + "leo_carat_last.icon", "leo_carat_right.icon", "leo_check_circle_filled.icon", "leo_check_circle_outline.icon", "leo_chrome_cast.icon", "leo_clipboard.icon", "leo_close.icon", + "leo_close_circle.icon", "leo_code.icon", "leo_copy.icon", "leo_copy_plain_text.icon", diff --git a/patches/chrome-browser-ui-views-location_bar-location_bar_view.cc.patch b/patches/chrome-browser-ui-views-location_bar-location_bar_view.cc.patch index f95f04428689..683666116487 100644 --- a/patches/chrome-browser-ui-views-location_bar-location_bar_view.cc.patch +++ b/patches/chrome-browser-ui-views-location_bar-location_bar_view.cc.patch @@ -1,5 +1,5 @@ diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc -index 8ad0bd147a4c2814e0890421fa65e94e301dd4c7..f6fe808012b4f2c229a5759b643366e782452c84 100644 +index 8ad0bd147a4c2814e0890421fa65e94e301dd4c7..59ad47179391fca50114914094670897c0024eec 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc @@ -717,6 +717,7 @@ void LocationBarView::Layout(PassKey) { @@ -10,7 +10,15 @@ index 8ad0bd147a4c2814e0890421fa65e94e301dd4c7..f6fe808012b4f2c229a5759b643366e7 if (should_indent) { icon_left += icon_indent; text_left += text_indent; -@@ -804,6 +805,7 @@ void LocationBarView::Layout(PassKey) { +@@ -780,6 +781,7 @@ void LocationBarView::Layout(PassKey) { + } + selected_keyword_view_->SetCustomImage(image); + } ++ BRAVE_LAYOUT_HANDLE_SEARCH_PROMOTION_BUTTON_VISIBILITY + } else if (location_icon_view_->GetShowText() && + !ShouldChipOverrideLocationIcon()) { + location_icon_view_->SetVisible(true); +@@ -804,6 +806,7 @@ void LocationBarView::Layout(PassKey) { } }; @@ -18,7 +26,7 @@ index 8ad0bd147a4c2814e0890421fa65e94e301dd4c7..f6fe808012b4f2c229a5759b643366e7 add_trailing_decoration(page_action_icon_container_, /*intra_item_padding=*/0); for (ContentSettingImageView* view : base::Reversed(content_setting_views_)) { -@@ -817,6 +819,7 @@ void LocationBarView::Layout(PassKey) { +@@ -817,6 +820,7 @@ void LocationBarView::Layout(PassKey) { } add_trailing_decoration(clear_all_button_, /*intra_item_padding=*/0);