File: popup_base_view.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (155 lines) | stat: -rw-r--r-- 5,968 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_POPUP_POPUP_BASE_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_POPUP_POPUP_BASE_VIEW_H_

#include <array>
#include <vector>

#include "base/containers/span.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "build/build_config.h"
#include "chrome/browser/ui/autofill/autofill_popup_view_delegate.h"
#include "chrome/browser/ui/views/autofill/popup/custom_cursor_suppressor.h"
#include "chrome/browser/ui/views/autofill/popup/popup_row_view.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/bubble/bubble_border_arrow_utils.h"
#include "ui/views/focus/widget_focus_manager.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/widget/widget_observer.h"

class Browser;

namespace autofill {

// Class that deals with the event handling for Autofill-style popups. This
// class should only be instantiated by sub-classes.
class PopupBaseView : public PopupRowView::AccessibilitySelectionDelegate,
                      public views::WidgetDelegateView,
                      public views::WidgetFocusChangeListener,
                      public views::WidgetObserver {
  METADATA_HEADER(PopupBaseView, views::WidgetDelegateView)

 public:
  // Consider the input element is `kElementBorderPadding` pixels larger at the
  // top and at the bottom in order to reposition the dropdown, so that it
  // doesn't look too close to the element.
  static constexpr int kElementBorderPadding = 1;

  // Default list of the preferred popup sides adjacent to the target element.
  static constexpr std::array<views::BubbleArrowSide, 4>
      kDefaultPreferredPopupSides = {
          views::BubbleArrowSide::kTop, views::BubbleArrowSide::kBottom,
          views::BubbleArrowSide::kLeft, views::BubbleArrowSide::kRight};

  PopupBaseView(const PopupBaseView&) = delete;
  PopupBaseView& operator=(const PopupBaseView&) = delete;

  static int GetCornerRadius();
  // Returns the horizontal margin between the arrow and the edge of the view.
  // Used to align child elements to the popup arrow.
  static int ArrowHorizontalMargin();

  // Notify accessibility that an item has been selected.
  void NotifyAXSelection(views::View& view) override;

  // Returns the browser in which this popup is shown.
  Browser* GetBrowser();

 protected:
  PopupBaseView(base::WeakPtr<AutofillPopupViewDelegate> delegate,
                views::Widget* parent_widget,
                views::Widget::InitParams::Activatable new_widget_activatable =
                    views::Widget::InitParams::Activatable::kDefault,
                bool show_arrow_pointer = true);
  ~PopupBaseView() override;

  // Show this popup. Idempotent. Returns |true| if popup is shown, |false|
  // otherwise.
  bool DoShow();

  // Hide the widget and delete |this|.
  void DoHide();

  // Ensure the child views are not rendered beyond the popup border
  // boundaries.
  void UpdateClipPath();

  // Returns the bounds of the containing browser window in screen space.
  gfx::Rect GetTopWindowBounds() const;

  // Returns the bounds of the content area in screen space.
  gfx::Rect GetContentAreaBounds() const;

  // Update size of popup and paint. If there is insufficient height to draw the
  // popup, it hides and thus deletes |this| and returns false. (virtual for
  // testing).
  [[nodiscard]] virtual bool DoUpdateBoundsAndRedrawPopup();

  // Returns the optimal bounds to place the popup with `preferred_size` and
  // places an arrow on the popup border to point towards `element_bounds`
  // within `max_bounds_for_popup`. The `preferred_popup_sides` are tried
  // one-by-one until a side with enough space is found.
  virtual gfx::Rect GetOptimalPositionAndPlaceArrowOnPopup(
      const gfx::Rect& element_bounds,
      const gfx::Rect& max_bounds_for_popup,
      const gfx::Size& preferred_size,
      base::span<const views::BubbleArrowSide> preferred_popup_sides);

 private:
  friend class PopupBaseViewBrowsertest;

  class Widget;

  // views::WidgetFocusChangeListener implementation.
  void OnNativeFocusChanged(gfx::NativeView focused_now) override;

  // views::WidgetObserver implementation.
  void OnWidgetBoundsChanged(views::Widget* widget,
                             const gfx::Rect& new_bounds) override;
  void OnWidgetDestroying(views::Widget* widget) override;

  // Stop observing the widget.
  void RemoveWidgetObservers();

  // Hide the controller of this view. This assumes that doing so will
  // eventually hide this view in the process.
  void HideController(SuggestionHidingReason reason);

  // Return the web contents related to this.
  content::WebContents* GetWebContents() const;

  // Scoped observation for focus events.
  base::ScopedObservation<views::WidgetFocusManager,
                          views::WidgetFocusChangeListener>
      focus_observation_{this};

  // Controller for this popup. Weak reference.
  base::WeakPtr<AutofillPopupViewDelegate> delegate_;

  // The widget of the window that triggered this popup. Weak reference.
  raw_ptr<views::Widget> parent_widget_ = nullptr;

  // The corresponding parameter for newly created widget (in `DoShow()`).
  const views::Widget::InitParams::Activatable new_widget_activatable_;

  const bool show_arrow_pointer_;

  // Ensures that the menu start event is not fired redundantly.
  bool is_ax_menu_start_event_fired_ = false;

  // Responsible for blocking (and re-enabling) custom cursors across all
  // browser windows.
  CustomCursorSuppressor custom_cursor_suppressor_;
};

}  // namespace autofill

#endif  // CHROME_BROWSER_UI_VIEWS_AUTOFILL_POPUP_POPUP_BASE_VIEW_H_