File: multi_contents_view_delegate.cc

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 (116 lines) | stat: -rw-r--r-- 4,694 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
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/frame/multi_contents_view_delegate.h"

#include "chrome/browser/sessions/session_service.h"
#include "chrome/browser/sessions/session_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/split_tab_metrics.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
#include "chrome/browser/ui/views/frame/multi_contents_drop_target_view.h"
#include "components/tabs/public/split_tab_data.h"
#include "components/tabs/public/split_tab_visual_data.h"

MultiContentsViewDelegateImpl::MultiContentsViewDelegateImpl(Browser& browser)
    : browser_(browser), tab_strip_model_(*browser.tab_strip_model()) {}

void MultiContentsViewDelegateImpl::WebContentsFocused(
    content::WebContents* web_contents) {
  int tab_index = tab_strip_model_->GetIndexOfWebContents(web_contents);
  if (tab_index != TabStripModel::kNoTab) {
    tab_strip_model_->ActivateTabAt(tab_index);
  }
}

void MultiContentsViewDelegateImpl::ReverseWebContents() {
  const int active_index = tab_strip_model_->active_index();

  const std::optional<split_tabs::SplitTabId> split_tab_id =
      tab_strip_model_->GetTabAtIndex(active_index)->GetSplit();

  CHECK(split_tab_id.has_value());
  tab_strip_model_->ReverseTabsInSplit(split_tab_id.value());
}

void MultiContentsViewDelegateImpl::ResizeWebContents(double start_ratio,
                                                      bool done_resizing) {
  const std::optional<split_tabs::SplitTabId> split_tab_id =
      tab_strip_model_->GetActiveTab()->GetSplit();

  CHECK(split_tab_id.has_value());
  tab_strip_model_->UpdateSplitRatio(split_tab_id.value(), start_ratio);

  if (done_resizing) {
    const split_tabs::SplitTabId split_id =
        tab_strip_model_->GetActiveTab()->GetSplit().value();

    SessionService* const session_service =
        SessionServiceFactory::GetForProfile(browser_->profile());

    if (!session_service) {
      return;
    }

    const split_tabs::SplitTabVisualData* visual_data =
        tab_strip_model_->GetSplitData(split_id)->visual_data();
    session_service->SetSplitTabData(browser_->session_id(), split_id,
                                     visual_data);
  }
}

void MultiContentsViewDelegateImpl::HandleLinkDrop(
    MultiContentsDropTargetView::DropSide side,
    const std::vector<GURL>& urls) {
  CHECK(!urls.empty());
  CHECK(!tab_strip_model_->GetActiveTab()->IsSplit());

  // Insert the tab before or after the active tab, according to the drop side.
  const int new_tab_idx =
      tab_strip_model_->active_index() +
      (side == MultiContentsDropTargetView::DropSide::START ? 0 : 1);

  // TODO(crbug.com/406792273): Support entrypoint for horizontal splits.
  const split_tabs::SplitTabVisualData split_data(
      split_tabs::SplitTabLayout::kVertical);

  // We currently only support creating a split with one link; i.e., the first
  // link in the provided list.
  tab_strip_model_->delegate()->AddTabAt(urls.front(), new_tab_idx,
                                         /*foreground=*/true);
  // Create a split with the previously active tab, which should be before or
  // after the newly created tab.
  tab_strip_model_->AddToNewSplit(
      {new_tab_idx +
       (side == MultiContentsDropTargetView::DropSide::START ? 1 : -1)},
      split_data, split_tabs::SplitTabCreatedSource::kDragAndDropLink);
}

void MultiContentsViewDelegateImpl::HandleTabDrop(
    MultiContentsDropTargetView::DropSide side,
    TabDragDelegate::DragController& drag_controller) {
  CHECK(!tab_strip_model_->GetActiveTab()->IsSplit());

  // TODO(crbug.com/406792273): Support entrypoint for horizontal splits.
  const split_tabs::SplitTabVisualData split_data(
      split_tabs::SplitTabLayout::kVertical);

  std::unique_ptr<tabs::TabModel> detached_tab =
      drag_controller.DetachTabAtForInsertion(
          drag_controller.GetSessionData().source_view_index_);

  // Insert the tab next to the currently active tab, add it to a split,
  // then activate it.
  const int new_tab_idx =
      tab_strip_model_->active_index() +
      (side == MultiContentsDropTargetView::DropSide::START ? 0 : 1);
  const int inserted_tab_idx = tab_strip_model_->InsertDetachedTabAt(
      new_tab_idx, std::move(detached_tab), AddTabTypes::ADD_NONE,
      std::nullopt);
  tab_strip_model_->AddToNewSplit(
      {inserted_tab_idx}, split_data,
      split_tabs::SplitTabCreatedSource::kDragAndDropTab);
  tab_strip_model_->ActivateTabAt(inserted_tab_idx);
}