File: browser_root_view.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (169 lines) | stat: -rw-r--r-- 6,300 bytes parent folder | download | duplicates (6)
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
// 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 CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_ROOT_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_ROOT_VIEW_H_

#include <memory>
#include <optional>

#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/widget/root_view.h"

class ToolbarView;

namespace ui {
class OSExchangeData;
}

// RootView implementation used by BrowserFrame. This forwards drop events to
// the TabStrip. Visually the tabstrip extends to the top of the frame, but in
// actually it doesn't. The tabstrip is only as high as a tab. To enable
// dropping above the tabstrip BrowserRootView forwards drop events to the
// TabStrip.
class BrowserRootView : public views::internal::RootView {
  METADATA_HEADER(BrowserRootView, views::internal::RootView)

 public:
  struct DropIndex {
    // The index within the tabstrip to drop on/before (see `relative_to_index`
    // below).
    int index = 0;

    // Whether the dropped item should be inserted before `index` or replace
    // the tab at `index`.
    enum class RelativeToIndex { kInsertBeforeIndex, kReplaceIndex };
    RelativeToIndex relative_to_index = RelativeToIndex::kReplaceIndex;

    // If `relative_to_index` is `kInsertBeforeIndex`, and `index` is the first
    // tab in a tab group, determines whether to drop in the group or just
    // before it. This disambiguates a drop before or after a group header.
    enum class GroupInclusion { kIncludeInGroup, kDontIncludeInGroup };
    GroupInclusion group_inclusion = GroupInclusion::kDontIncludeInGroup;

    bool operator==(const DropIndex& other) const = default;
  };

  class DropTarget {
   public:
    DropTarget(const DropTarget&) = delete;
    DropTarget& operator=(const DropTarget&) = delete;

    // Returns a `DropIndex` for the drop. Returns `nullopt` if it is not
    // possible to drop at this location.
    virtual std::optional<DropIndex> GetDropIndex(
        const ui::DropTargetEvent& event) = 0;
    virtual DropTarget* GetDropTarget(gfx::Point loc_in_local_coords) = 0;
    virtual views::View* GetViewForDrop() = 0;

    virtual void HandleDragUpdate(const std::optional<DropIndex>& index) {}
    virtual void HandleDragExited() {}

   protected:
    DropTarget() = default;
    virtual ~DropTarget() = default;
  };

  // You must call set_tabstrip before this class will accept drops.
  BrowserRootView(BrowserView* browser_view, views::Widget* widget);
  BrowserRootView(const BrowserRootView&) = delete;
  BrowserRootView& operator=(const BrowserRootView&) = delete;
  ~BrowserRootView() override;

  // views::View:
  bool GetDropFormats(int* formats,
                      std::set<ui::ClipboardFormatType>* format_types) override;
  bool AreDropTypesRequired() override;
  bool CanDrop(const ui::OSExchangeData& data) override;
  void OnDragEntered(const ui::DropTargetEvent& event) override;
  int OnDragUpdated(const ui::DropTargetEvent& event) override;
  void OnDragExited() override;
  DropCallback GetDropCallback(const ui::DropTargetEvent& event) override;
  bool OnMouseWheel(const ui::MouseWheelEvent& event) override;
  void OnMouseExited(const ui::MouseEvent& event) override;
  gfx::Size CalculatePreferredSize(
      const views::SizeBounds& available_size) const override;

 protected:
  // views::View:
  void PaintChildren(const views::PaintInfo& paint_info) override;

 private:
  friend class BrowserRootViewBrowserTest;
  FRIEND_TEST_ALL_PREFIXES(BrowserRootViewBrowserTest, ClearDropInfo);
  FRIEND_TEST_ALL_PREFIXES(BrowserRootViewBrowserTest, DropOrderingCorrect);
  FRIEND_TEST_ALL_PREFIXES(BrowserRootViewBrowserTest,
                           InitiatorOriginForDroppedLink);

  // Used during a drop session of a url. Tracks the position of the drop.
  struct DropInfo {
    DropInfo();
    ~DropInfo();

    raw_ptr<DropTarget, DanglingUntriaged> target = nullptr;

    // Where to drop the urls.
    std::optional<DropIndex> index;

    // The validated URLs for the drop event.
    std::vector<GURL> urls;

    // An incrementing sequence number for `DropInfo`s.
    int sequence = 0;

    // Set to true when the filtering of the URLs being dropped is complete.
    bool filtering_complete = false;
  };

  // Converts `event` from the hosts coordinate system to the view's
  // coordinate system, and gets the `DropIndex` for the drop.
  std::optional<DropIndex> GetDropIndexForEvent(
      const ui::DropTargetEvent& event,
      const ui::OSExchangeData& data,
      DropTarget* target);

  DropTarget* GetDropTarget(const ui::DropTargetEvent& event);

  // Called when the filtering for supported URLs is complete.
  void OnFilteringComplete(int sequence, std::vector<GURL> urls);

  // Sets a callback for when URL filtering is complete. Be sure to wait for
  // filtering to be complete before checking the drag operation returned by
  // `OnDragUpdated()` or calling the drop callback in tests.
  void SetOnFilteringCompleteClosureForTesting(base::OnceClosure closure);

  TabStrip* tabstrip() { return browser_view_->tabstrip(); }
  ToolbarView* toolbar() { return browser_view_->toolbar(); }

  // Returns a URL if |data| has string contents and the user can "paste and
  // go".
  std::optional<GURL> GetPasteAndGoURL(const ui::OSExchangeData& data);

  // Navigates to the dropped URLs.
  void NavigateToDroppedUrls(
      std::unique_ptr<DropInfo> drop_info,
      const ui::DropTargetEvent& event,
      ui::mojom::DragOperation& output_drag_op,
      std::unique_ptr<ui::LayerTreeOwner> drag_image_layer_owner);

  // The BrowserView.
  raw_ptr<BrowserView, AcrossTasksDanglingUntriaged> browser_view_ = nullptr;

  // Used to calculate partial offsets in scrolls that occur for a smooth
  // scroll device.
  int scroll_remainder_x_ = 0;
  int scroll_remainder_y_ = 0;

  std::unique_ptr<DropInfo> drop_info_;

  base::OnceClosure on_filtering_complete_closure_;

  base::WeakPtrFactory<BrowserRootView> weak_ptr_factory_{this};
};

#endif  // CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_ROOT_VIEW_H_