| diff --git ui/base/models/menu_model.h ui/base/models/menu_model.h |
| index a6d70c71a1b3a..1b628f5284409 100644 |
| --- ui/base/models/menu_model.h |
| +++ ui/base/models/menu_model.h |
| @@ -17,8 +17,11 @@ |
| #include "ui/color/color_id.h" |
| #include "ui/gfx/native_widget_types.h" |
| |
| +#include "third_party/skia/include/core/SkColor.h" |
| + |
| namespace gfx { |
| class FontList; |
| +class Point; |
| } |
| |
| namespace ui { |
| @@ -147,6 +150,27 @@ class COMPONENT_EXPORT(UI_BASE) MenuModel |
| // |event_flags| is a bit mask of ui::EventFlags. |
| virtual void ActivatedAt(size_t index, int event_flags); |
| |
| + // Called when the user moves the mouse outside the menu and over the owning |
| + // window. |
| + virtual void MouseOutsideMenu(const gfx::Point& screen_point) {} |
| + |
| + // Called on unhandled open/close submenu keyboard commands. |is_rtl| will be |
| + // true if the menu is displaying a right-to-left language. |
| + virtual void UnhandledOpenSubmenu(bool is_rtl) {} |
| + virtual void UnhandledCloseSubmenu(bool is_rtl) {} |
| + |
| + // Override the text/background color of a given menu item dependent on the |
| + // |index| and its |is_hovered| state. |is_minor| will be true for accelerator |
| + // text. Returns true if it chooses to override the color. |
| + virtual bool GetTextColor(size_t index, |
| + bool is_minor, |
| + bool is_hovered, |
| + SkColor* override_color) const { return false; } |
| + virtual bool GetBackgroundColor(size_t index, |
| + bool is_hovered, |
| + SkColor* override_color) const |
| + { return false; } |
| + |
| // Called when the menu is about to be shown. |
| virtual void MenuWillShow() {} |
| |
| diff --git ui/gfx/render_text.cc ui/gfx/render_text.cc |
| index dab8c9be8d902..5951ec36a874e 100644 |
| --- ui/gfx/render_text.cc |
| +++ ui/gfx/render_text.cc |
| @@ -670,6 +670,14 @@ void RenderText::SetWhitespaceElision(absl::optional<bool> whitespace_elision) { |
| } |
| } |
| |
| +void RenderText::SetDrawStringsFlags(int flags) { |
| + if (draw_strings_flags_ == flags) |
| + return; |
| + draw_strings_flags_ = flags; |
| + cached_bounds_and_offset_valid_ = false; |
| + OnTextAttributeChanged(); |
| +} |
| + |
| void RenderText::SetDisplayRect(const Rect& r) { |
| if (r != display_rect_) { |
| display_rect_ = r; |
| @@ -2061,6 +2069,19 @@ void RenderText::OnTextAttributeChanged() { |
| |
| layout_text_up_to_date_ = false; |
| |
| + if (draw_strings_flags_ != 0) { |
| + // Compute layout size with the mnemonic character underlined since it might |
| + // be larger than with the underline hidden. |
| + int char_pos = -1; |
| + int char_span = 0; |
| + layout_text_ = |
| + gfx::LocateAndRemoveAcceleratorChar(layout_text_, &char_pos, &char_span); |
| + if (char_pos != -1) { |
| + gfx::Range range(char_pos, char_pos + char_span); |
| + styles_[TEXT_STYLE_UNDERLINE].ApplyValue(true, range); |
| + } |
| + } |
| + |
| OnLayoutTextAttributeChanged(true); |
| } |
| |
| diff --git ui/gfx/render_text.h ui/gfx/render_text.h |
| index 212c98c242ed3..26f9bb4c28400 100644 |
| --- ui/gfx/render_text.h |
| +++ ui/gfx/render_text.h |
| @@ -347,6 +347,10 @@ class GFX_EXPORT RenderText { |
| return whitespace_elision_; |
| } |
| |
| + // Get or set the flags that control display of accelerator characters. |
| + void SetDrawStringsFlags(int flags); |
| + int draw_strings_flags() const { return draw_strings_flags_; } |
| + |
| const Rect& display_rect() const { return display_rect_; } |
| void SetDisplayRect(const Rect& r); |
| |
| @@ -1056,6 +1060,8 @@ class GFX_EXPORT RenderText { |
| |
| // Tell whether or not the |layout_text_| needs an update or is up to date. |
| mutable bool layout_text_up_to_date_ = false; |
| + |
| + int draw_strings_flags_ = 0; |
| }; |
| |
| } // namespace gfx |
| diff --git ui/views/animation/ink_drop_host.h ui/views/animation/ink_drop_host.h |
| index c1c0631071a11..aa2c01ebce43e 100644 |
| --- ui/views/animation/ink_drop_host.h |
| +++ ui/views/animation/ink_drop_host.h |
| @@ -194,6 +194,8 @@ class VIEWS_EXPORT InkDropHost { |
| View* host_view() { return host_view_; } |
| const View* host_view() const { return host_view_; } |
| |
| + InkDropMode ink_drop_mode() const { return ink_drop_mode_; } |
| + |
| private: |
| friend class test::InkDropHostTestApi; |
| |
| diff --git ui/views/controls/button/label_button.cc ui/views/controls/button/label_button.cc |
| index c7b00c3852d02..be30a1995d570 100644 |
| --- ui/views/controls/button/label_button.cc |
| +++ ui/views/controls/button/label_button.cc |
| @@ -566,6 +566,12 @@ void LabelButton::OnThemeChanged() { |
| SchedulePaint(); |
| } |
| |
| +void LabelButton::SetFontList(const gfx::FontList& font_list) { |
| + cached_normal_font_list_ = font_list; |
| + cached_default_button_font_list_ = font_list; |
| + label_->SetFontList(cached_normal_font_list_); |
| +} |
| + |
| void LabelButton::StateChanged(ButtonState old_state) { |
| Button::StateChanged(old_state); |
| ResetLabelEnabledColor(); |
| diff --git ui/views/controls/button/label_button.h ui/views/controls/button/label_button.h |
| index 8dbd918f09528..06fad642642c4 100644 |
| --- ui/views/controls/button/label_button.h |
| +++ ui/views/controls/button/label_button.h |
| @@ -155,6 +155,9 @@ class VIEWS_EXPORT LabelButton : public Button, public NativeThemeDelegate { |
| ui::NativeTheme::State GetForegroundThemeState( |
| ui::NativeTheme::ExtraParams* params) const override; |
| |
| + // Sets the font list used by this button. |
| + void SetFontList(const gfx::FontList& font_list); |
| + |
| protected: |
| ImageView* image() const { return image_; } |
| Label* label() const { return label_; } |
| diff --git ui/views/controls/label.cc ui/views/controls/label.cc |
| index a1a17ca0f4090..ad4ac7a2678e0 100644 |
| --- ui/views/controls/label.cc |
| +++ ui/views/controls/label.cc |
| @@ -53,12 +53,29 @@ enum LabelPropertyKey { |
| kLabelLineHeight, |
| kLabelObscured, |
| kLabelAllowCharacterBreak, |
| + kLabelDrawStringsFlags, |
| }; |
| |
| bool IsOpaque(SkColor color) { |
| return SkColorGetA(color) == SK_AlphaOPAQUE; |
| } |
| |
| +// Strips accelerator character prefixes in |text| if needed, based on |flags|. |
| +// Returns a range in |text| to underline or Range::InvalidRange() if |
| +// underlining is not needed. |
| +gfx::Range StripAcceleratorChars(int flags, std::u16string* text) { |
| + if (flags & (gfx::Canvas::SHOW_PREFIX | gfx::Canvas::HIDE_PREFIX)) { |
| + int char_pos = -1; |
| + int char_span = 0; |
| + *text = gfx::LocateAndRemoveAcceleratorChar(*text, &char_pos, &char_span); |
| + if ((flags & gfx::Canvas::SHOW_PREFIX) && char_pos != -1) { |
| + return gfx::Range(static_cast<size_t>(char_pos), |
| + static_cast<size_t>(char_pos + char_span)); |
| + } |
| + } |
| + return gfx::Range::InvalidRange(); |
| +} |
| + |
| } // namespace |
| |
| namespace views { |
| @@ -474,6 +491,15 @@ void Label::SetElideBehavior(gfx::ElideBehavior elide_behavior) { |
| OnPropertyChanged(&elide_behavior_, kPropertyEffectsPreferredSizeChanged); |
| } |
| |
| +void Label::SetDrawStringsFlags(int flags) { |
| + if (draw_strings_flags_ == flags) |
| + return; |
| + draw_strings_flags_ = flags; |
| + full_text_->SetDrawStringsFlags(draw_strings_flags_); |
| + OnPropertyChanged(&full_text_ + kLabelDrawStringsFlags, |
| + kPropertyEffectsPreferredSizeChanged); |
| +} |
| + |
| std::u16string Label::GetTooltipText() const { |
| return tooltip_text_; |
| } |
| @@ -778,6 +804,16 @@ std::unique_ptr<gfx::RenderText> Label::CreateRenderText() const { |
| render_text->SelectRange(stored_selection_range_); |
| } |
| |
| + if (draw_strings_flags_ != 0) { |
| + auto text_str = GetText(); |
| + gfx::Range range = StripAcceleratorChars(draw_strings_flags_, &text_str); |
| + render_text->SetText(text_str); |
| + if (range.IsValid()) { |
| + render_text->SetDisplayRect(bounds()); |
| + render_text->ApplyStyle(gfx::TEXT_STYLE_UNDERLINE, true, range); |
| + } |
| + } |
| + |
| return render_text; |
| } |
| |
| diff --git ui/views/controls/label.h ui/views/controls/label.h |
| index 711dc633bffc2..0fa2626150de2 100644 |
| --- ui/views/controls/label.h |
| +++ ui/views/controls/label.h |
| @@ -240,6 +240,10 @@ class VIEWS_EXPORT Label : public View, |
| gfx::ElideBehavior GetElideBehavior() const; |
| void SetElideBehavior(gfx::ElideBehavior elide_behavior); |
| |
| + // Get or set the flags that control display of accelerator characters. |
| + void SetDrawStringsFlags(int flags); |
| + int GetDrawStringsFlags() const { return draw_strings_flags_; } |
| + |
| // Gets/Sets the tooltip text. Default behavior for a label (single-line) is |
| // to show the full text if it is wider than its bounds. Calling this |
| // overrides the default behavior and lets you set a custom tooltip. To |
| @@ -504,6 +508,7 @@ class VIEWS_EXPORT Label : public View, |
| int max_width_ = 0; |
| // This is used in single-line mode. |
| int max_width_single_line_ = 0; |
| + int draw_strings_flags_ = 0; |
| |
| std::unique_ptr<SelectionController> selection_controller_; |
| |
| diff --git ui/views/controls/menu/menu_controller.cc ui/views/controls/menu/menu_controller.cc |
| index b02f25526d9cb..2961ef6ba1185 100644 |
| --- ui/views/controls/menu/menu_controller.cc |
| +++ ui/views/controls/menu/menu_controller.cc |
| @@ -565,7 +565,8 @@ void MenuController::Run(Widget* parent, |
| MenuAnchorPosition position, |
| bool context_menu, |
| bool is_nested_drag, |
| - gfx::NativeView native_view_for_gestures) { |
| + gfx::NativeView native_view_for_gestures, |
| + gfx::AcceleratedWidget parent_widget) { |
| exit_type_ = ExitType::kNone; |
| possible_drag_ = false; |
| drag_in_progress_ = false; |
| @@ -610,6 +611,7 @@ void MenuController::Run(Widget* parent, |
| owner_->AddObserver(this); |
| |
| native_view_for_gestures_ = native_view_for_gestures; |
| + parent_widget_ = parent_widget; |
| |
| // Only create a MenuPreTargetHandler for non-nested menus. Nested menus |
| // will use the existing one. |
| @@ -2230,6 +2232,7 @@ void MenuController::OpenMenuImpl(MenuItemView* item, bool show) { |
| params.do_capture = do_capture; |
| params.native_view_for_gestures = native_view_for_gestures_; |
| params.owned_window_anchor = anchor; |
| + params.parent_widget = parent_widget_; |
| if (item->GetParentMenuItem()) { |
| params.context = item->GetWidget(); |
| // (crbug.com/1414232) The item to be open is a submenu. Make sure |
| @@ -2915,8 +2918,13 @@ MenuItemView* MenuController::FindInitialSelectableMenuItem( |
| |
| void MenuController::OpenSubmenuChangeSelectionIfCan() { |
| MenuItemView* item = pending_state_.item; |
| - if (!item->HasSubmenu() || !item->GetEnabled()) |
| + if (!item->HasSubmenu() || !item->GetEnabled() || !item->GetParentMenuItem()) { |
| + MenuItemView* submenu_item = |
| + item->GetParentMenuItem() ? item->GetParentMenuItem() : item; |
| + submenu_item->GetDelegate()->OnUnhandledOpenSubmenu(submenu_item, |
| + base::i18n::IsRTL()); |
| return; |
| + } |
| |
| // Show the sub-menu. |
| SetSelection(item, SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); |
| @@ -2936,8 +2944,10 @@ void MenuController::OpenSubmenuChangeSelectionIfCan() { |
| void MenuController::CloseSubmenu() { |
| MenuItemView* item = state_.item; |
| DCHECK(item); |
| - if (!item->GetParentMenuItem()) |
| + if (!item->GetParentMenuItem()) { |
| + item->GetDelegate()->OnUnhandledCloseSubmenu(item, base::i18n::IsRTL()); |
| return; |
| + } |
| if (item->SubmenuIsShowing()) |
| SetSelection(item, SELECTION_UPDATE_IMMEDIATELY); |
| else if (item->GetParentMenuItem()->GetParentMenuItem()) |
| diff --git ui/views/controls/menu/menu_controller.h ui/views/controls/menu/menu_controller.h |
| index 97c1f62da483b..2c8a52f562147 100644 |
| --- ui/views/controls/menu/menu_controller.h |
| +++ ui/views/controls/menu/menu_controller.h |
| @@ -138,7 +138,9 @@ class VIEWS_EXPORT MenuController |
| MenuAnchorPosition position, |
| bool context_menu, |
| bool is_nested_drag, |
| - gfx::NativeView native_view_for_gestures = gfx::NativeView()); |
| + gfx::NativeView native_view_for_gestures = gfx::NativeView(), |
| + gfx::AcceleratedWidget parent_widget = |
| + gfx::kNullAcceleratedWidget); |
| |
| bool for_drop() const { return for_drop_; } |
| |
| @@ -722,6 +724,8 @@ class VIEWS_EXPORT MenuController |
| // RunType::SEND_GESTURE_EVENTS_TO_OWNER is set. |
| gfx::NativeView native_view_for_gestures_ = gfx::NativeView(); |
| |
| + gfx::AcceleratedWidget parent_widget_ = gfx::kNullAcceleratedWidget; |
| + |
| // Indicates a possible drag operation. |
| bool possible_drag_ = false; |
| |
| diff --git ui/views/controls/menu/menu_delegate.h ui/views/controls/menu/menu_delegate.h |
| index b8fa1c116ebcd..015f15ed72385 100644 |
| --- ui/views/controls/menu/menu_delegate.h |
| +++ ui/views/controls/menu/menu_delegate.h |
| @@ -73,6 +73,22 @@ class VIEWS_EXPORT MenuDelegate { |
| virtual const gfx::FontList* GetLabelFontList(int id) const; |
| virtual absl::optional<SkColor> GetLabelColor(int id) const; |
| |
| + // Override the text color of a given menu item dependent on the |command_id| |
| + // and its |is_hovered| state. |is_minor| will be true for accelerator text. |
| + // Returns true if it chooses to override the color. |
| + virtual bool GetTextColor(int command_id, |
| + bool is_minor, |
| + bool is_hovered, |
| + SkColor* override_color) const { return false; } |
| + |
| + // Override the background color of a given menu item dependent on the |
| + // |command_id| and its |is_hovered| state. Returns true if it chooses to |
| + // override the color. |
| + virtual bool GetBackgroundColor(int command_id, |
| + bool is_hovered, |
| + SkColor* override_color) const |
| + { return false; } |
| + |
| // The tooltip shown for the menu item. This is invoked when the user |
| // hovers over the item, and no tooltip text has been set for that item. |
| virtual std::u16string GetTooltipText(int id, |
| @@ -201,6 +217,11 @@ class VIEWS_EXPORT MenuDelegate { |
| bool* has_mnemonics, |
| MenuButton** button); |
| |
| + // Called on unhandled open/close submenu keyboard commands. |is_rtl| will be |
| + // true if the menu is displaying a right-to-left language. |
| + virtual void OnUnhandledOpenSubmenu(MenuItemView* menu, bool is_rtl) {} |
| + virtual void OnUnhandledCloseSubmenu(MenuItemView* menu, bool is_rtl) {} |
| + |
| // Returns the max width menus can grow to be. |
| virtual int GetMaxWidthForMenu(MenuItemView* menu); |
| |
| diff --git ui/views/controls/menu/menu_host.cc ui/views/controls/menu/menu_host.cc |
| index 2da9d8fb49d8d..9f344ff8180f1 100644 |
| --- ui/views/controls/menu/menu_host.cc |
| +++ ui/views/controls/menu/menu_host.cc |
| @@ -141,6 +141,8 @@ void MenuHost::InitMenuHost(const InitParams& init_params) { |
| : gfx::NativeWindow(); |
| params.bounds = init_params.bounds; |
| |
| + params.parent_widget = init_params.parent_widget; |
| + |
| #if defined(USE_AURA) |
| // TODO(msisov): remove kMenutype once positioning of anchored windows |
| // finally migrates to a new path. |
| @@ -152,7 +154,8 @@ void MenuHost::InitMenuHost(const InitParams& init_params) { |
| // If MenuHost has no parent widget, it needs to be marked |
| // Activatable, so that calling Show in ShowMenuHost will |
| // get keyboard focus. |
| - if (init_params.parent == nullptr) |
| + if (init_params.parent == nullptr && |
| + init_params.parent_widget == gfx::kNullAcceleratedWidget) |
| params.activatable = Widget::InitParams::Activatable::kYes; |
| |
| #if BUILDFLAG(IS_WIN) |
| diff --git ui/views/controls/menu/menu_host.h ui/views/controls/menu/menu_host.h |
| index 10c4ecd08f76b..062f0c58bb805 100644 |
| --- ui/views/controls/menu/menu_host.h |
| +++ ui/views/controls/menu/menu_host.h |
| @@ -53,6 +53,8 @@ class MenuHost : public Widget, public WidgetObserver { |
| // Additional information that helps to position anchored windows in such |
| // backends as Wayland. |
| ui::OwnedWindowAnchor owned_window_anchor; |
| + |
| + gfx::AcceleratedWidget parent_widget = gfx::kNullAcceleratedWidget; |
| }; |
| |
| explicit MenuHost(SubmenuView* submenu); |
| diff --git ui/views/controls/menu/menu_item_view.cc ui/views/controls/menu/menu_item_view.cc |
| index bbb50ca16f67e..9217236ef056b 100644 |
| --- ui/views/controls/menu/menu_item_view.cc |
| +++ ui/views/controls/menu/menu_item_view.cc |
| @@ -1057,6 +1057,15 @@ void MenuItemView::PaintBackground(gfx::Canvas* canvas, |
| spilling_rect.set_y(spilling_rect.y() - corner_radius_); |
| spilling_rect.set_height(spilling_rect.height() + corner_radius_); |
| canvas->DrawRoundRect(spilling_rect, corner_radius_, flags); |
| + return; |
| + } |
| + |
| + MenuDelegate *delegate = GetDelegate(); |
| + SkColor override_color; |
| + if (delegate && delegate->GetBackgroundColor(GetCommand(), |
| + paint_as_selected, |
| + &override_color)) { |
| + canvas->DrawColor(override_color); |
| } else if (paint_as_selected) { |
| gfx::Rect item_bounds = GetLocalBounds(); |
| if (type_ == Type::kActionableSubMenu) { |
| @@ -1121,6 +1130,13 @@ void MenuItemView::PaintMinorIconAndText(gfx::Canvas* canvas, SkColor color) { |
| } |
| |
| SkColor MenuItemView::GetTextColor(bool minor, bool paint_as_selected) const { |
| + SkColor text_color; |
| + const MenuDelegate *delegate = GetDelegate(); |
| + if (delegate && delegate->GetTextColor(GetCommand(), minor, paint_as_selected, |
| + &text_color)) { |
| + return text_color; |
| + } |
| + |
| // Use a custom color if provided by the controller. If the item is selected, |
| // use the default color. |
| if (!paint_as_selected && foreground_color_id_.has_value()) { |
| diff --git ui/views/controls/menu/menu_model_adapter.cc ui/views/controls/menu/menu_model_adapter.cc |
| index 887f471c4db69..5d097994cbf72 100644 |
| --- ui/views/controls/menu/menu_model_adapter.cc |
| +++ ui/views/controls/menu/menu_model_adapter.cc |
| @@ -4,6 +4,7 @@ |
| |
| #include "ui/views/controls/menu/menu_model_adapter.h" |
| |
| +#include <limits> |
| #include <list> |
| #include <memory> |
| #include <utility> |
| @@ -225,6 +226,76 @@ bool MenuModelAdapter::IsItemChecked(int id) const { |
| return model->IsItemCheckedAt(index); |
| } |
| |
| +MenuItemView* MenuModelAdapter::GetSiblingMenu(MenuItemView* menu, |
| + const gfx::Point& screen_point, |
| + MenuAnchorPosition* anchor, |
| + bool* has_mnemonics, |
| + MenuButton** button) { |
| + // Look up the menu model for this menu. |
| + const std::map<MenuItemView*, ui::MenuModel*>::const_iterator map_iterator = |
| + menu_map_.find(menu); |
| + if (map_iterator != menu_map_.end()) { |
| + map_iterator->second->MouseOutsideMenu(screen_point); |
| + return nullptr; |
| + } |
| + |
| + NOTREACHED(); |
| + return nullptr; |
| +} |
| + |
| +void MenuModelAdapter::OnUnhandledOpenSubmenu(MenuItemView* menu, |
| + bool is_rtl) { |
| + // Look up the menu model for this menu. |
| + const std::map<MenuItemView*, ui::MenuModel*>::const_iterator map_iterator = |
| + menu_map_.find(menu); |
| + if (map_iterator != menu_map_.end()) { |
| + map_iterator->second->UnhandledOpenSubmenu(is_rtl); |
| + return; |
| + } |
| + |
| + NOTREACHED(); |
| +} |
| + |
| +void MenuModelAdapter::OnUnhandledCloseSubmenu(MenuItemView* menu, |
| + bool is_rtl) { |
| + // Look up the menu model for this menu. |
| + const std::map<MenuItemView*, ui::MenuModel*>::const_iterator map_iterator = |
| + menu_map_.find(menu); |
| + if (map_iterator != menu_map_.end()) { |
| + map_iterator->second->UnhandledCloseSubmenu(is_rtl); |
| + return; |
| + } |
| + |
| + NOTREACHED(); |
| +} |
| + |
| +bool MenuModelAdapter::GetTextColor(int command_id, |
| + bool is_minor, |
| + bool is_hovered, |
| + SkColor* override_color) const { |
| + ui::MenuModel* model = menu_model_; |
| + size_t index = 0; |
| + if (ui::MenuModel::GetModelAndIndexForCommandId(command_id, &model, &index)) |
| + return model->GetTextColor(index, is_minor, is_hovered, override_color); |
| + |
| + // Return the default color. |
| + return menu_model_->GetBackgroundColor(std::numeric_limits<size_t>::max(), |
| + is_hovered, override_color); |
| +} |
| + |
| +bool MenuModelAdapter::GetBackgroundColor(int command_id, |
| + bool is_hovered, |
| + SkColor* override_color) const { |
| + ui::MenuModel* model = menu_model_; |
| + size_t index = 0; |
| + if (ui::MenuModel::GetModelAndIndexForCommandId(command_id, &model, &index)) |
| + return model->GetBackgroundColor(index, is_hovered, override_color); |
| + |
| + // Return the default color. |
| + return menu_model_->GetBackgroundColor(std::numeric_limits<size_t>::max(), |
| + is_hovered, override_color); |
| +} |
| + |
| void MenuModelAdapter::WillShowMenu(MenuItemView* menu) { |
| // Look up the menu model for this menu. |
| const std::map<MenuItemView*, ui::MenuModel*>::const_iterator map_iterator = |
| diff --git ui/views/controls/menu/menu_model_adapter.h ui/views/controls/menu/menu_model_adapter.h |
| index a8354c0699920..9b5deb522c29a 100644 |
| --- ui/views/controls/menu/menu_model_adapter.h |
| +++ ui/views/controls/menu/menu_model_adapter.h |
| @@ -89,6 +89,20 @@ class VIEWS_EXPORT MenuModelAdapter : public MenuDelegate, |
| bool IsCommandEnabled(int id) const override; |
| bool IsCommandVisible(int id) const override; |
| bool IsItemChecked(int id) const override; |
| + MenuItemView* GetSiblingMenu(MenuItemView* menu, |
| + const gfx::Point& screen_point, |
| + MenuAnchorPosition* anchor, |
| + bool* has_mnemonics, |
| + MenuButton** button) override; |
| + void OnUnhandledOpenSubmenu(MenuItemView* menu, bool is_rtl) override; |
| + void OnUnhandledCloseSubmenu(MenuItemView* menu, bool is_rtl) override; |
| + bool GetTextColor(int command_id, |
| + bool is_minor, |
| + bool is_hovered, |
| + SkColor* override_color) const override; |
| + bool GetBackgroundColor(int command_id, |
| + bool is_hovered, |
| + SkColor* override_color) const override; |
| void WillShowMenu(MenuItemView* menu) override; |
| void WillHideMenu(MenuItemView* menu) override; |
| void OnMenuClosed(MenuItemView* menu) override; |
| diff --git ui/views/controls/menu/menu_runner.cc ui/views/controls/menu/menu_runner.cc |
| index adb22671b94fa..59cc421e82e1b 100644 |
| --- ui/views/controls/menu/menu_runner.cc |
| +++ ui/views/controls/menu/menu_runner.cc |
| @@ -36,6 +36,7 @@ void MenuRunner::RunMenuAt(Widget* parent, |
| MenuAnchorPosition anchor, |
| ui::MenuSourceType source_type, |
| gfx::NativeView native_view_for_gestures, |
| + gfx::AcceleratedWidget parent_widget, |
| absl::optional<gfx::RoundedCornersF> corners) { |
| // Do not attempt to show the menu if the application is currently shutting |
| // down. MenuDelegate::OnMenuClosed would not be called. |
| @@ -82,7 +83,7 @@ void MenuRunner::RunMenuAt(Widget* parent, |
| } |
| |
| impl_->RunMenuAt(parent, button_controller, bounds, anchor, run_types_, |
| - native_view_for_gestures, corners); |
| + native_view_for_gestures, parent_widget, corners); |
| } |
| |
| bool MenuRunner::IsRunning() const { |
| diff --git ui/views/controls/menu/menu_runner.h ui/views/controls/menu/menu_runner.h |
| index 562b67396f27f..7679dbd79e565 100644 |
| --- ui/views/controls/menu/menu_runner.h |
| +++ ui/views/controls/menu/menu_runner.h |
| @@ -152,6 +152,8 @@ class VIEWS_EXPORT MenuRunner { |
| MenuAnchorPosition anchor, |
| ui::MenuSourceType source_type, |
| gfx::NativeView native_view_for_gestures = gfx::NativeView(), |
| + gfx::AcceleratedWidget parent_widget = |
| + gfx::kNullAcceleratedWidget, |
| absl::optional<gfx::RoundedCornersF> corners = absl::nullopt); |
| |
| // Returns true if we're in a nested run loop running the menu. |
| diff --git ui/views/controls/menu/menu_runner_impl.cc ui/views/controls/menu/menu_runner_impl.cc |
| index e82249ad5e887..3a7429bcaf9f1 100644 |
| --- ui/views/controls/menu/menu_runner_impl.cc |
| +++ ui/views/controls/menu/menu_runner_impl.cc |
| @@ -117,6 +117,7 @@ void MenuRunnerImpl::RunMenuAt(Widget* parent, |
| MenuAnchorPosition anchor, |
| int32_t run_types, |
| gfx::NativeView native_view_for_gestures, |
| + gfx::AcceleratedWidget parent_widget, |
| absl::optional<gfx::RoundedCornersF> corners) { |
| closing_event_time_ = base::TimeTicks(); |
| if (running_) { |
| @@ -184,7 +185,7 @@ void MenuRunnerImpl::RunMenuAt(Widget* parent, |
| controller->Run(parent, button_controller, menu_, bounds, anchor, |
| (run_types & MenuRunner::CONTEXT_MENU) != 0, |
| (run_types & MenuRunner::NESTED_DRAG) != 0, |
| - native_view_for_gestures); |
| + native_view_for_gestures, parent_widget); |
| } |
| |
| void MenuRunnerImpl::Cancel() { |
| diff --git ui/views/controls/menu/menu_runner_impl.h ui/views/controls/menu/menu_runner_impl.h |
| index 4d2909b5094ab..245e1a24dd810 100644 |
| --- ui/views/controls/menu/menu_runner_impl.h |
| +++ ui/views/controls/menu/menu_runner_impl.h |
| @@ -53,6 +53,7 @@ class VIEWS_EXPORT MenuRunnerImpl : public MenuRunnerImplInterface, |
| MenuAnchorPosition anchor, |
| int32_t run_types, |
| gfx::NativeView native_view_for_gestures, |
| + gfx::AcceleratedWidget parent_widget, |
| absl::optional<gfx::RoundedCornersF> corners = absl::nullopt) override; |
| void Cancel() override; |
| base::TimeTicks GetClosingEventTime() const override; |
| diff --git ui/views/controls/menu/menu_runner_impl_adapter.cc ui/views/controls/menu/menu_runner_impl_adapter.cc |
| index b6c680063889b..a1efa677a43a5 100644 |
| --- ui/views/controls/menu/menu_runner_impl_adapter.cc |
| +++ ui/views/controls/menu/menu_runner_impl_adapter.cc |
| @@ -34,9 +34,10 @@ void MenuRunnerImplAdapter::RunMenuAt( |
| MenuAnchorPosition anchor, |
| int32_t types, |
| gfx::NativeView native_view_for_gestures, |
| + gfx::AcceleratedWidget parent_widget, |
| absl::optional<gfx::RoundedCornersF> corners) { |
| impl_->RunMenuAt(parent, button_controller, bounds, anchor, types, |
| - native_view_for_gestures); |
| + native_view_for_gestures, parent_widget); |
| } |
| |
| void MenuRunnerImplAdapter::Cancel() { |
| diff --git ui/views/controls/menu/menu_runner_impl_adapter.h ui/views/controls/menu/menu_runner_impl_adapter.h |
| index e6587d2208a13..c2c72f7edb89c 100644 |
| --- ui/views/controls/menu/menu_runner_impl_adapter.h |
| +++ ui/views/controls/menu/menu_runner_impl_adapter.h |
| @@ -44,6 +44,7 @@ class VIEWS_EXPORT MenuRunnerImplAdapter : public MenuRunnerImplInterface { |
| MenuAnchorPosition anchor, |
| int32_t types, |
| gfx::NativeView native_view_for_gestures, |
| + gfx::AcceleratedWidget parent_widget, |
| absl::optional<gfx::RoundedCornersF> corners = absl::nullopt) override; |
| void Cancel() override; |
| base::TimeTicks GetClosingEventTime() const override; |
| diff --git ui/views/controls/menu/menu_runner_impl_cocoa.h ui/views/controls/menu/menu_runner_impl_cocoa.h |
| index 2325534ec9243..7573a54cc891c 100644 |
| --- ui/views/controls/menu/menu_runner_impl_cocoa.h |
| +++ ui/views/controls/menu/menu_runner_impl_cocoa.h |
| @@ -42,6 +42,7 @@ class VIEWS_EXPORT MenuRunnerImplCocoa : public MenuRunnerImplInterface { |
| MenuAnchorPosition anchor, |
| int32_t run_types, |
| gfx::NativeView native_view_for_gestures, |
| + gfx::AcceleratedWidget parent_widget, |
| absl::optional<gfx::RoundedCornersF> corners = absl::nullopt) override; |
| void Cancel() override; |
| base::TimeTicks GetClosingEventTime() const override; |
| diff --git ui/views/controls/menu/menu_runner_impl_cocoa.mm ui/views/controls/menu/menu_runner_impl_cocoa.mm |
| index c3c80f6becee7..5b6fc116f6255 100644 |
| --- ui/views/controls/menu/menu_runner_impl_cocoa.mm |
| +++ ui/views/controls/menu/menu_runner_impl_cocoa.mm |
| @@ -190,6 +190,7 @@ void MenuRunnerImplCocoa::RunMenuAt( |
| MenuAnchorPosition anchor, |
| int32_t run_types, |
| gfx::NativeView native_view_for_gestures, |
| + gfx::AcceleratedWidget /*parent_widget*/, |
| absl::optional<gfx::RoundedCornersF> corners) { |
| DCHECK(!IsRunning()); |
| DCHECK(parent); |
| diff --git ui/views/controls/menu/menu_runner_impl_interface.h ui/views/controls/menu/menu_runner_impl_interface.h |
| index cf696fbcf0714..5c48fd7410b88 100644 |
| --- ui/views/controls/menu/menu_runner_impl_interface.h |
| +++ ui/views/controls/menu/menu_runner_impl_interface.h |
| @@ -46,6 +46,8 @@ class MenuRunnerImplInterface { |
| MenuAnchorPosition anchor, |
| int32_t run_types, |
| gfx::NativeView native_view_for_gestures, |
| + gfx::AcceleratedWidget parent_widget = |
| + gfx::kNullAcceleratedWidget, |
| absl::optional<gfx::RoundedCornersF> corners = absl::nullopt) = 0; |
| |
| // Hides and cancels the menu. |
| diff --git ui/views/controls/menu/menu_scroll_view_container.cc ui/views/controls/menu/menu_scroll_view_container.cc |
| index 8c093e002326c..3a500adcd39bb 100644 |
| --- ui/views/controls/menu/menu_scroll_view_container.cc |
| +++ ui/views/controls/menu/menu_scroll_view_container.cc |
| @@ -250,6 +250,11 @@ MenuScrollViewContainer::MenuScrollViewContainer(SubmenuView* content_view) |
| scroll_down_button_ = background_view_->AddChildView( |
| std::make_unique<MenuScrollButton>(content_view, false)); |
| |
| + SkColor override_color; |
| + MenuDelegate* delegate = content_view_->GetMenuItem()->GetDelegate(); |
| + if (delegate && delegate->GetBackgroundColor(-1, false, &override_color)) |
| + SetBackground(views::CreateSolidBackground(override_color)); |
| + |
| arrow_ = BubbleBorderTypeFromAnchor( |
| content_view_->GetMenuItem()->GetMenuController()->GetAnchorPosition()); |
| |
| diff --git ui/views/test/ui_controls_factory_desktop_aura_ozone.cc ui/views/test/ui_controls_factory_desktop_aura_ozone.cc |
| index 187e55af5d7be..3a980d26fdaae 100644 |
| --- ui/views/test/ui_controls_factory_desktop_aura_ozone.cc |
| +++ ui/views/test/ui_controls_factory_desktop_aura_ozone.cc |
| @@ -15,6 +15,7 @@ |
| #include "base/task/single_thread_task_runner.h" |
| #include "build/build_config.h" |
| #include "build/chromeos_buildflags.h" |
| +#include "cef/libcef/features/features.h" |
| #include "ui/aura/client/screen_position_client.h" |
| #include "ui/aura/env.h" |
| #include "ui/aura/test/aura_test_utils.h" |
| @@ -176,9 +177,11 @@ bool SendMouseMoveNotifyWhenDone(int screen_x, |
| aura::test::QueryLatestMousePositionRequestInHost(host); |
| host->ConvertPixelsToDIP(&root_current_location); |
| |
| +#if !BUILDFLAG(ENABLE_CEF) |
| auto* screen = views::test::TestDesktopScreenOzone::GetInstance(); |
| DCHECK_EQ(screen, display::Screen::GetScreen()); |
| screen->set_cursor_screen_point(gfx::Point(screen_x, screen_y)); |
| +#endif |
| |
| #if !BUILDFLAG(IS_CHROMEOS_LACROS) |
| if (root_location != root_current_location && |
| diff --git ui/views/view.h ui/views/view.h |
| index 80a2b76b266f5..17b85ef182b55 100644 |
| --- ui/views/view.h |
| +++ ui/views/view.h |
| @@ -21,6 +21,7 @@ |
| #include "base/memory/raw_ptr.h" |
| #include "base/observer_list.h" |
| #include "base/strings/string_piece.h" |
| +#include "base/supports_user_data.h" |
| #include "build/build_config.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| #include "third_party/skia/include/core/SkPath.h" |
| @@ -283,7 +284,8 @@ class VIEWS_EXPORT View : public ui::LayerDelegate, |
| public ui::EventTarget, |
| public ui::EventHandler, |
| public ui::PropertyHandler, |
| - public ui::metadata::MetaDataProvider { |
| + public ui::metadata::MetaDataProvider, |
| + public base::SupportsUserData { |
| public: |
| using Views = std::vector<View*>; |
| |