File: menu_runner.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; 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,806; 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 (198 lines) | stat: -rw-r--r-- 7,764 bytes parent folder | download | duplicates (5)
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_VIEWS_CONTROLS_MENU_MENU_RUNNER_H_
#define UI_VIEWS_CONTROLS_MENU_MENU_RUNNER_H_

#include <stdint.h>

#include <memory>
#include <optional>
#include <string>

#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "ui/base/mojom/menu_source_type.mojom-forward.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/controls/menu/menu_types.h"
#include "ui/views/views_export.h"

namespace base {
class TimeTicks;
}

namespace gfx {
class Rect;
}  // namespace gfx

namespace ui {
class MenuModel;
}

namespace views {

class MenuButtonController;
class MenuItemView;
class MenuRunnerHandler;
class Widget;

namespace internal {
class MenuRunnerImplInterface;
}

namespace test {
class MenuRunnerTestAPI;
}

// MenuRunner is responsible for showing (running) the menu and additionally
// owning the MenuItemView. It is safe to delete MenuRunner at any point, but
// MenuRunner will not notify you of the closure caused by a deletion.
// If MenuRunner is deleted while the menu is showing the delegate of the menu
// is reset. This is done to ensure delegates aren't notified after they may
// have been deleted.
//
// Similarly you should avoid creating MenuRunner on the stack. Doing so means
// MenuRunner may not be immediately destroyed if your object is destroyed,
// resulting in possible callbacks to your now deleted object. Instead you
// should define MenuRunner as a scoped_ptr in your class so that when your
// object is destroyed MenuRunner initiates the proper cleanup and ensures your
// object isn't accessed again.
class VIEWS_EXPORT MenuRunner {
 public:
  enum RunTypes {
    NO_FLAGS = 0,

    // The menu has mnemonics.
    HAS_MNEMONICS = 1 << 0,

    // The menu is a nested context menu. For example, click a folder on the
    // bookmark bar, then right click an entry to get its context menu.
    IS_NESTED = 1 << 1,

    // Used for showing a menu during a drop operation. This does NOT block the
    // caller, instead the delegate is notified when the menu closes via the
    // DropMenuClosed method.
    FOR_DROP = 1 << 2,

    // The menu is a context menu (not necessarily nested), for example right
    // click on a link on a website in the browser.
    CONTEXT_MENU = 1 << 3,

    // The menu should behave like a Windows native Combobox dropdow menu.
    // This behavior includes accepting the pending item and closing on F4.
    COMBOBOX = 1 << 4,

    // A child view is performing a drag-and-drop operation, so the menu should
    // stay open (even if it doesn't receive drag updated events). In this case,
    // the caller is responsible for closing the menu upon completion of the
    // drag-and-drop.
    NESTED_DRAG = 1 << 5,

    // Menu with fixed anchor position, so |MenuRunner| will not attempt to
    // adjust the anchor point. For example the context menu of shelf item.
    FIXED_ANCHOR = 1 << 6,

    // The menu's owner could be in the middle of a gesture when the menu opens
    // and can use this flag to continue the gesture. For example, Chrome OS's
    // shelf uses the flag to continue dragging an item without lifting the
    // finger after the context menu of the item is opened.
    SEND_GESTURE_EVENTS_TO_OWNER = 1 << 7,

    // Applying the system UI specific layout to the context menu. This should
    // be set for the context menu inside system UI only (e.g, the context menu
    // while right clicking the wallpaper of a ChromeBook). Thus, this can be
    // used to differentiate the context menu inside system UI from others. It
    // is useful if we want to customize some attributes of the context menu
    // inside system UI, e.g, colors.
    USE_ASH_SYS_UI_LAYOUT = 1 << 8,

    // Similar to COMBOBOX, but does not capture the mouse and lets some keys
    // propagate back to the parent so the combobox content can be edited even
    // while the menu is open.
    EDITABLE_COMBOBOX = 1 << 9,

    // Indicates that the menu should show mnemonics.
    SHOULD_SHOW_MNEMONICS = 1 << 10,

    // Indicates that the menu was invoked from the keyboard.
    INVOKED_FROM_KEYBOARD = 1 << 11,

    // The menu is a context menu (not necessarily nested) for a menu item, for
    // example right click on bookmark drop-down.
    MENU_ITEM_CONTEXT_MENU = 1 << 12,
  };

  // Creates a new MenuRunner, which may use a native menu if available.
  // |run_types| is a bitmask of RunTypes. If provided,
  // |on_menu_closed_callback| is invoked when the menu is closed.
  // The MenuModelDelegate of |menu_model| will be overwritten by this call.
  MenuRunner(ui::MenuModel* menu_model,
             int32_t run_types,
             base::RepeatingClosure on_menu_closed_callback =
                 base::RepeatingClosure());

  // Creates a runner for a custom-created toolkit-views menu.
  MenuRunner(std::unique_ptr<MenuItemView> menu, int32_t run_types);

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

  ~MenuRunner();

  // Runs the menu. MenuDelegate::OnMenuClosed will be notified of the results.
  // If `anchor` uses a `BUBBLE_..` type, the bounds will get determined by
  // using `bounds` as the thing to point at in screen coordinates.
  // `native_view_for_gestures` is a NativeView that is used for cases where the
  // surface hosting the menu has a different gfx::NativeView than the `parent`.
  // This is required to correctly route gesture events to the correct
  // NativeView in the cases where the surface hosting the menu is a
  // WebContents.
  // `corners` assigns the customized `RoundedCornersF` to the context menu. If
  // it's set, the passed in corner will be used to render each corner radius of
  // the context menu. This only works when using `USE_ASH_SYS_UI_LAYOUT`.
  // Note that this is a blocking call for a native menu on Mac. See
  // http://crbug.com/682544.
  // `show_menu_host_duration_histogram` is the name of the histogram measuring
  // time from when Widget::Show() is called to when the first frame is
  // presented for menu. It is recorded in MenuHost and it happens only when the
  // histogram name is non-empty.
  void RunMenuAt(Widget* parent,
                 MenuButtonController* button_controller,
                 const gfx::Rect& bounds,
                 MenuAnchorPosition anchor,
                 ui::mojom::MenuSourceType source_type,
                 gfx::NativeView native_view_for_gestures = gfx::NativeView(),
                 std::optional<gfx::RoundedCornersF> corners = std::nullopt,
                 std::optional<std::string> show_menu_host_duration_histogram =
                     std::nullopt);

  // Returns true if we're in a nested run loop running the menu.
  bool IsRunning() const;

  // Hides and cancels the menu. This does nothing if the menu is not open.
  void Cancel();

  // Returns the time from the event which closed the menu - or 0.
  base::TimeTicks closing_event_time() const;

 private:
  friend class test::MenuRunnerTestAPI;

  // Sets an implementation of RunMenuAt. This is intended to be used at test.
  void SetRunnerHandler(std::unique_ptr<MenuRunnerHandler> runner_handler);

  const int32_t run_types_;

  // We own this. No scoped_ptr because it is destroyed by calling Release().
  raw_ptr<internal::MenuRunnerImplInterface> impl_;

  // An implementation of RunMenuAt. This is usually NULL and ignored. If this
  // is not NULL, this implementation will be used.
  std::unique_ptr<MenuRunnerHandler> runner_handler_;
};

}  // namespace views

#endif  // UI_VIEWS_CONTROLS_MENU_MENU_RUNNER_H_