File: tab_dialog_manager.h

package info (click to toggle)
chromium 140.0.7339.185-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,193,740 kB
  • sloc: cpp: 35,093,945; ansic: 7,161,670; javascript: 4,199,694; python: 1,441,797; asm: 949,904; xml: 747,515; pascal: 187,748; perl: 88,691; sh: 88,248; objc: 79,953; sql: 52,714; cs: 44,599; fortran: 24,137; makefile: 22,114; tcl: 15,277; php: 13,980; yacc: 9,000; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (186 lines) | stat: -rw-r--r-- 7,766 bytes parent folder | download | duplicates (3)
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
// Copyright 2024 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_TABS_PUBLIC_TAB_DIALOG_MANAGER_H_
#define CHROME_BROWSER_UI_TABS_PUBLIC_TAB_DIALOG_MANAGER_H_

#include <memory>
#include <optional>
#include <vector>

#include "base/callback_list.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "components/tabs/public/tab_interface.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/geometry/rect.h"

namespace gfx {
class LinearAnimation;
}  // namespace gfx

namespace views {
class Widget;
class WidgetObserver;
class DialogDelegate;
}  // namespace views

namespace tabs {

class TabDialogWidgetObserver;

// Class provides a mechanism to show a tab-scoped dialog on desktop platforms.
// Please file a bug if you encounter any issues.
class TabDialogManager : public content::WebContentsObserver,
                         public gfx::AnimationDelegate {
 public:
  using ShouldShowCallback = base::RepeatingCallback<void(bool&)>;
  using GetDialogBounds = base::RepeatingCallback<gfx::Rect()>;
  explicit TabDialogManager(TabInterface* tab_interface);
  TabDialogManager(const TabDialogManager&) = delete;
  TabDialogManager& operator=(const TabDialogManager&) = delete;
  ~TabDialogManager() override;

  // Parameters that are used to configure the behavior of the tab dialog.
  struct Params {
    Params();
    ~Params();
    // If the tab's main frame performs a different-site navigation, close the
    // dialog.
    bool close_on_navigate = true;

    // If the tab is detached, close the dialog.
    bool close_on_detach = true;

    // Disable input on the underlying WebContents.
    bool disable_input = true;

    // If true, the dialog will animate its bounds changes. This is not
    // compatible with `views::Widget::InitParams::autosize`. The client is
    // responsible for calling `UpdateModalDialogBounds()` when the dialog size
    // changes to trigger the animation.
    bool animated = false;

    // Ensure that TabInterface::CanShowModalUI() reflects whether another modal
    // dialog can be shown while another is currently being shown. When this
    // flag is false, a subsequent dialog will hide/dismiss the existing dialog.
    bool block_new_modal = true;

    // Assign a callback here if the client intends to handle all sizing and
    // positioning responsibilities. Useful for when the dialog is a bubble
    // or similar and needs different positioning logic.
    GetDialogBounds get_dialog_bounds;

    // By default, TabDialogManager will show the widget if the tab is visible,
    // and the browser window is not minimized. This callback can be set to add
    // an additional condition that will be checked to determine widget
    // visibility.
    ShouldShowCallback should_show_callback;
  };

  // Create a dialog widget from the given DialogDelegate suitable for showing
  // as scoped to a tab.
  std::unique_ptr<views::Widget> CreateTabScopedDialog(
      views::DialogDelegate* delegate);
  // Shows a widget scoped to the associated `tab_interface_`. Only one
  // tab-scoped dialog widget may be shown at a time. Interrogate
  // TabInterface::CanShowModalUI() to determine whether it is safe to call this
  // function. The dialog is centered above the hosting view as obtained via
  // TabInterface::GetBrowserWindowInterface() and will be shown/hidden along
  // with the tab. Currently, the returned widget's ownership model is still
  // dependent on ownership within the DialogDelegate. If the call-site
  // ownership hasn't been migrated to CLIENT_OWNS_WIDGET or
  // WIDGET_OWNS_NATIVE_WIDGET, do not hold on to the Widget as a unique_ptr.
  // TODO(kylixrd):
  //   (1) Call-sites expect to own the Widget using CLIENT_OWNS_WIDGET and be
  //       updated accordingly.
  void ShowDialog(views::Widget* dialog, std::unique_ptr<Params> params);
  // Combines the above two functions into a single invocation. This is the most
  // commonly used version. Only use the other APIs if the caller must do
  // something special with the widget.
  std::unique_ptr<views::Widget> CreateAndShowDialog(
      views::DialogDelegate* delegate,
      std::unique_ptr<Params> params);

  void CloseDialog();

  // Activates the dialog if applicable. Returns true if the dialog was
  // activated. This returns false in a few cases:
  //  * If there is no dialog.
  //  * If the associated tab is not active.
  //  * If the browser window is minimized.
  bool MaybeActivateDialog();

  // Resets all state associated with `widget_`.
  // Called in two different circumstances:
  //  * From an internal WidgetObserver when the Widget is in the process of
  //    being destroyed by external code.
  //  * From CloseDialog(), right before calling Close() on the widget.
  void WidgetDestroyed(views::Widget* widget);

  // Returns the widget associated with the browser window. This widget is used
  // as the parent for tab-scoped widgets.
  views::Widget* GetHostWidget() const;

  // Updates the bounds of the modal dialog. If `Params::animated` is true, this
  // will animate the bounds change. Clients with non-autosized dialogs should
  // call this when the dialog's preferred size changes.
  void UpdateModalDialogBounds();

  // Trigger the dialog manager to re-evaluate the dialog's visibility.
  // Optionally pass in a `requested_visibility` which is the state the client
  // thinks the dialog should be in, assuming the tab is visible and the window
  // is not minimized. This will also make sure the `should_show_callback` is
  // properly invoked and update the widget's visibility accordingly. Clients
  // should call this when their internal state has changed which may affect the
  // currently showing dialog's visibility. Function returns the new visibility
  // state of the dialog.
  bool UpdateDialogVisibility(
      std::optional<bool> requested_visibility = std::nullopt);

  // Overridden from gfx::AnimationDelegate:
  void AnimationProgressed(const gfx::Animation* animation) override;
  void AnimationEnded(const gfx::Animation* animation) override;

 private:
  class BrowserWindowWidgetObserver;
  friend class BrowserWindowWidgetObserver;
  //  Overridden from content::WebContentObserver:
  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override;

  void TabDidEnterForeground(TabInterface* tab_interface);
  void TabWillEnterBackground(TabInterface* tab_interface);
  void TabWillDetach(TabInterface* tab_interface,
                     TabInterface::DetachReason reason);

  bool GetDialogWidgetVisibility();

  raw_ptr<TabInterface> tab_interface_ = nullptr;

  // Holds subscriptions for TabInterface callbacks.
  std::vector<base::CallbackListSubscription> tab_subscriptions_;

  // Active dialog and associated state. These members should be set and cleared
  // simultaneously.
  raw_ptr<views::Widget> widget_;
  std::optional<content::WebContents::ScopedIgnoreInputEvents>
      scoped_ignore_input_events_;
  std::unique_ptr<TabDialogWidgetObserver> tab_dialog_widget_observer_;
  std::unique_ptr<BrowserWindowWidgetObserver> browser_window_widget_observer_;
  std::unique_ptr<ScopedTabModalUI> showing_modal_ui_;
  std::unique_ptr<Params> params_;

  // For animating the dialog bounds.
  gfx::Rect animation_start_bounds_;
  gfx::Rect animation_target_bounds_;
  std::unique_ptr<gfx::LinearAnimation> bounds_animation_;
};

}  // namespace tabs

#endif  // CHROME_BROWSER_UI_TABS_PUBLIC_TAB_DIALOG_MANAGER_H_