This source file includes following definitions.
- GetEffectiveBounds
- initial_move_
- CaptureDragInfo
- EndDrag
- GetDraggedTabForContents
- IsDraggingTab
- IsDraggingWebContents
- IsTabDetached
- InitDraggedTabData
- OpenURLFromTab
- NavigationStateChanged
- AddNewContents
- LoadingStateChanged
- GetJavaScriptDialogManager
- Observe
- RequestMediaAccessPermission
- GetWindowCreatePoint
- ContinueDragging
- RestoreSelection
- MoveAttached
- MoveDetached
- GetTabStripForPoint
- GetTabStripIfItContains
- Attach
- Detach
- ConvertScreenPointToTabStripPoint
- GetDraggedViewTabStripBounds
- GetInsertionIndexForDraggedBounds
- GetDraggedViewPoint
- NormalizeIndexToAttachedTabStrip
- GetTabMatchingDraggedContents
- GetTabsMatchingDraggedContents
- SetDraggedTabsVisible
- EndDragImpl
- RevertDrag
- CompleteDrag
- ResetDelegates
- EnsureDraggedView
- GetAnimateBounds
- HideWindow
- ShowWindow
- CleanUpHiddenFrame
- CleanUpDraggedTabs
- OnAnimateToBoundsComplete
- BringWindowUnderMouseToFront
- AreTabsConsecutive
- GetLocalProcessWindow
#include "chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.h"
#include <algorithm>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/i18n/rtl.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/gtk/browser_window_gtk.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/gtk/tabs/dragged_view_gtk.h"
#include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h"
#include "chrome/browser/ui/gtk/tabs/window_finder.h"
#include "chrome/browser/ui/media_utils.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "ui/base/gtk/gtk_screen_util.h"
#include "ui/gfx/screen.h"
using content::OpenURLParams;
using content::WebContents;
namespace {
const int kBringToFrontDelay = 750;
const int kHorizontalMoveThreshold = 16;
const int kVerticalDetachMagnetism = 15;
gfx::Rect GetEffectiveBounds(const gfx::Rect& bounds) {
gfx::Rect effective_bounds(bounds);
effective_bounds.set_width(effective_bounds.width() - 2 * 16);
effective_bounds.set_x(effective_bounds.x() + 16);
return effective_bounds;
}
}
DraggedTabControllerGtk::DraggedTabControllerGtk(
TabStripGtk* source_tabstrip,
TabGtk* source_tab,
const std::vector<TabGtk*>& tabs)
: source_tabstrip_(source_tabstrip),
attached_tabstrip_(source_tabstrip),
in_destructor_(false),
last_move_screen_x_(0),
initial_move_(true) {
DCHECK(!tabs.empty());
DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end());
std::vector<DraggedTabData> drag_data;
for (size_t i = 0; i < tabs.size(); i++)
drag_data.push_back(InitDraggedTabData(tabs[i]));
int source_tab_index =
std::find(tabs.begin(), tabs.end(), source_tab) - tabs.begin();
drag_data_.reset(new DragData(drag_data, source_tab_index));
}
DraggedTabControllerGtk::~DraggedTabControllerGtk() {
in_destructor_ = true;
CleanUpDraggedTabs();
dragged_view_.reset();
drag_data_.reset();
}
void DraggedTabControllerGtk::CaptureDragInfo(const gfx::Point& mouse_offset) {
start_screen_point_ = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
mouse_offset_ = mouse_offset;
}
void DraggedTabControllerGtk::Drag() {
if (!drag_data_->GetSourceTabData()->tab_ ||
!drag_data_->GetSourceWebContents()) {
return;
}
bring_to_front_timer_.Stop();
EnsureDraggedView();
if (drag_data_->GetSourceTabData()->tab_->IsVisible()) {
Attach(source_tabstrip_, gfx::Point());
}
if (!drag_data_->GetSourceTabData()->tab_->IsVisible()) {
ContinueDragging();
}
}
bool DraggedTabControllerGtk::EndDrag(bool canceled) {
return EndDragImpl(canceled ? CANCELED : NORMAL);
}
TabGtk* DraggedTabControllerGtk::GetDraggedTabForContents(
WebContents* contents) {
if (attached_tabstrip_ == source_tabstrip_) {
for (size_t i = 0; i < drag_data_->size(); i++) {
if (contents == drag_data_->get(i)->contents_)
return drag_data_->get(i)->tab_;
}
}
return NULL;
}
bool DraggedTabControllerGtk::IsDraggingTab(const TabGtk* tab) {
for (size_t i = 0; i < drag_data_->size(); i++) {
if (tab == drag_data_->get(i)->tab_)
return true;
}
return false;
}
bool DraggedTabControllerGtk::IsDraggingWebContents(
const WebContents* web_contents) {
for (size_t i = 0; i < drag_data_->size(); i++) {
if (web_contents == drag_data_->get(i)->contents_)
return true;
}
return false;
}
bool DraggedTabControllerGtk::IsTabDetached(const TabGtk* tab) {
return IsDraggingTab(tab) && attached_tabstrip_ == NULL;
}
DraggedTabData DraggedTabControllerGtk::InitDraggedTabData(TabGtk* tab) {
int source_model_index = source_tabstrip_->GetIndexOfTab(tab);
WebContents* contents =
source_tabstrip_->model()->GetWebContentsAt(source_model_index);
bool pinned = source_tabstrip_->IsTabPinned(tab);
bool mini = source_tabstrip_->model()->IsMiniTab(source_model_index);
content::WebContentsDelegate* original_delegate = contents->GetDelegate();
contents->SetDelegate(this);
DraggedTabData dragged_tab_data(tab, contents, original_delegate,
source_model_index, pinned, mini);
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
content::Source<WebContents>(contents));
return dragged_tab_data;
}
WebContents* DraggedTabControllerGtk::OpenURLFromTab(
WebContents* source,
const OpenURLParams& params) {
if (drag_data_->GetSourceTabData()->original_delegate_) {
OpenURLParams forward_params = params;
if (params.disposition == CURRENT_TAB)
forward_params.disposition = NEW_WINDOW;
return drag_data_->GetSourceTabData()->original_delegate_->
OpenURLFromTab(source, forward_params);
}
return NULL;
}
void DraggedTabControllerGtk::NavigationStateChanged(const WebContents* source,
unsigned changed_flags) {
if (dragged_view_.get())
dragged_view_->Update();
}
void DraggedTabControllerGtk::AddNewContents(WebContents* source,
WebContents* new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
bool user_gesture,
bool* was_blocked) {
DCHECK(disposition != CURRENT_TAB);
if (drag_data_->GetSourceTabData()->original_delegate_) {
drag_data_->GetSourceTabData()->original_delegate_->AddNewContents(
source, new_contents, disposition, initial_pos, user_gesture,
was_blocked);
}
}
void DraggedTabControllerGtk::LoadingStateChanged(WebContents* source) {
if (dragged_view_.get())
dragged_view_->Update();
}
content::JavaScriptDialogManager*
DraggedTabControllerGtk::GetJavaScriptDialogManager() {
return GetJavaScriptDialogManagerInstance();
}
void DraggedTabControllerGtk::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type);
WebContents* destroyed_web_contents =
content::Source<WebContents>(source).ptr();
for (size_t i = 0; i < drag_data_->size(); ++i) {
if (drag_data_->get(i)->contents_ == destroyed_web_contents) {
if (destroyed_web_contents->GetDelegate() == this)
destroyed_web_contents->SetDelegate(NULL);
drag_data_->get(i)->contents_ = NULL;
drag_data_->get(i)->original_delegate_ = NULL;
EndDragImpl(TAB_DESTROYED);
return;
}
}
NOTREACHED();
}
void DraggedTabControllerGtk::RequestMediaAccessPermission(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
const content::MediaResponseCallback& callback) {
::RequestMediaAccessPermission(
web_contents,
Profile::FromBrowserContext(web_contents->GetBrowserContext()),
request,
callback);
}
gfx::Point DraggedTabControllerGtk::GetWindowCreatePoint() const {
gfx::Point creation_point =
gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
gfx::Point distance_from_origin =
dragged_view_->GetDistanceFromTabStripOriginToMousePointer();
creation_point.Offset(-distance_from_origin.x(), -distance_from_origin.y());
return creation_point;
}
void DraggedTabControllerGtk::ContinueDragging() {
gfx::Point screen_point =
gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
TabStripGtk* target_tabstrip = GetTabStripForPoint(screen_point);
if (target_tabstrip != attached_tabstrip_) {
if (attached_tabstrip_)
Detach();
if (target_tabstrip)
Attach(target_tabstrip, screen_point);
}
if (!target_tabstrip) {
bring_to_front_timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kBringToFrontDelay), this,
&DraggedTabControllerGtk::BringWindowUnderMouseToFront);
}
if (attached_tabstrip_)
MoveAttached(screen_point);
else
MoveDetached(screen_point);
}
void DraggedTabControllerGtk::RestoreSelection(TabStripModel* model) {
for (size_t i = 0; i < drag_data_->size(); ++i) {
WebContents* contents = drag_data_->get(i)->contents_;
if (contents) {
int index = model->GetIndexOfWebContents(contents);
CHECK(index != TabStripModel::kNoTab);
model->AddTabAtToSelection(index);
}
}
}
void DraggedTabControllerGtk::MoveAttached(const gfx::Point& screen_point) {
DCHECK(attached_tabstrip_);
gfx::Point dragged_view_point = GetDraggedViewPoint(screen_point);
TabStripModel* attached_model = attached_tabstrip_->model();
std::vector<TabGtk*> tabs(drag_data_->GetDraggedTabs());
double unselected, selected;
attached_tabstrip_->GetCurrentTabWidths(&unselected, &selected);
double ratio = unselected / TabGtk::GetStandardSize().width();
int threshold = static_cast<int>(ratio * kHorizontalMoveThreshold);
if (abs(screen_point.x() - last_move_screen_x_) > threshold ||
(initial_move_ && !AreTabsConsecutive())) {
if (initial_move_ && !AreTabsConsecutive()) {
attached_tabstrip_->model()->MoveSelectedTabsTo(
drag_data_->GetSourceTabData()->source_model_index_ -
drag_data_->source_tab_index());
}
gfx::Rect bounds = GetDraggedViewTabStripBounds(dragged_view_point);
int to_index = GetInsertionIndexForDraggedBounds(
GetEffectiveBounds(bounds));
to_index = NormalizeIndexToAttachedTabStrip(to_index);
last_move_screen_x_ = screen_point.x();
attached_model->MoveSelectedTabsTo(to_index);
}
dragged_view_->MoveAttachedTo(dragged_view_point);
initial_move_ = false;
}
void DraggedTabControllerGtk::MoveDetached(const gfx::Point& screen_point) {
DCHECK(!attached_tabstrip_);
dragged_view_->MoveDetachedTo(screen_point);
}
TabStripGtk* DraggedTabControllerGtk::GetTabStripForPoint(
const gfx::Point& screen_point) {
gfx::NativeWindow local_window = GetLocalProcessWindow(screen_point);
if (!local_window)
return NULL;
BrowserWindowGtk* browser =
BrowserWindowGtk::GetBrowserWindowForNativeWindow(local_window);
if (!browser)
return NULL;
TabStripGtk* other_tabstrip = browser->tabstrip();
if (!other_tabstrip->IsCompatibleWith(source_tabstrip_))
return NULL;
return GetTabStripIfItContains(other_tabstrip, screen_point);
}
TabStripGtk* DraggedTabControllerGtk::GetTabStripIfItContains(
TabStripGtk* tabstrip, const gfx::Point& screen_point) const {
gfx::Rect tabstrip_bounds =
ui::GetWidgetScreenBounds(tabstrip->tabstrip_.get());
if (screen_point.x() < tabstrip_bounds.right() &&
screen_point.x() >= tabstrip_bounds.x()) {
int upper_threshold = tabstrip_bounds.bottom() + kVerticalDetachMagnetism;
int lower_threshold = tabstrip_bounds.y() - kVerticalDetachMagnetism;
if (screen_point.y() >= lower_threshold &&
screen_point.y() <= upper_threshold) {
return tabstrip;
}
}
return NULL;
}
void DraggedTabControllerGtk::Attach(TabStripGtk* attached_tabstrip,
const gfx::Point& screen_point) {
attached_tabstrip_ = attached_tabstrip;
attached_tabstrip_->GenerateIdealBounds();
std::vector<TabGtk*> attached_dragged_tabs =
GetTabsMatchingDraggedContents(attached_tabstrip_);
int tab_count = attached_tabstrip_->GetTabCount();
int mini_tab_count = attached_tabstrip_->GetMiniTabCount();
if (attached_dragged_tabs.size() == 0) {
tab_count += drag_data_->size();
mini_tab_count += drag_data_->mini_tab_count();
}
double unselected_width = 0, selected_width = 0;
attached_tabstrip_->GetDesiredTabWidths(tab_count, mini_tab_count,
&unselected_width, &selected_width);
GtkWidget* parent_window = gtk_widget_get_parent(
gtk_widget_get_parent(attached_tabstrip_->tabstrip_.get()));
gfx::Rect window_bounds = ui::GetWidgetScreenBounds(parent_window);
dragged_view_->Attach(static_cast<int>(floor(selected_width + 0.5)),
TabGtk::GetMiniWidth(), window_bounds.width());
if (attached_dragged_tabs.size() == 0) {
for (size_t i = 0; i < drag_data_->size(); ++i) {
drag_data_->get(i)->contents_->SetDelegate(NULL);
drag_data_->get(i)->original_delegate_ = NULL;
}
attached_tabstrip_->GenerateIdealBounds();
last_move_screen_x_ = screen_point.x();
gfx::Rect bounds =
GetDraggedViewTabStripBounds(GetDraggedViewPoint(screen_point));
int index = GetInsertionIndexForDraggedBounds(GetEffectiveBounds(bounds));
for (size_t i = 0; i < drag_data_->size(); ++i) {
attached_tabstrip_->model()->InsertWebContentsAt(
index + i, drag_data_->get(i)->contents_,
drag_data_->GetAddTypesForDraggedTabAt(i));
}
RestoreSelection(attached_tabstrip_->model());
attached_dragged_tabs = GetTabsMatchingDraggedContents(attached_tabstrip_);
}
DCHECK(attached_dragged_tabs.size() == drag_data_->size());
SetDraggedTabsVisible(false, false);
}
void DraggedTabControllerGtk::Detach() {
TabStripModel* attached_model = attached_tabstrip_->model();
for (size_t i = 0; i < drag_data_->size(); ++i) {
int index =
attached_model->GetIndexOfWebContents(drag_data_->get(i)->contents_);
if (index >= 0 && index < attached_model->count()) {
attached_model->DetachWebContentsAt(index);
}
}
if (attached_model->empty())
HideWindow();
if (dragged_view_.get()) {
dragged_view_->Detach();
}
for (size_t i = 0; i < drag_data_->size(); ++i)
drag_data_->get(i)->contents_->SetDelegate(this);
attached_tabstrip_ = NULL;
}
gfx::Point DraggedTabControllerGtk::ConvertScreenPointToTabStripPoint(
TabStripGtk* tabstrip, const gfx::Point& screen_point) {
return screen_point - ui::GetWidgetScreenOffset(tabstrip->tabstrip_.get());
}
gfx::Rect DraggedTabControllerGtk::GetDraggedViewTabStripBounds(
const gfx::Point& screen_point) {
gfx::Point client_point =
ConvertScreenPointToTabStripPoint(attached_tabstrip_, screen_point);
gfx::Size tab_size = dragged_view_->attached_tab_size();
return gfx::Rect(client_point.x(), client_point.y(),
dragged_view_->GetTotalWidthInTabStrip(), tab_size.height());
}
int DraggedTabControllerGtk::GetInsertionIndexForDraggedBounds(
const gfx::Rect& dragged_bounds) {
int dragged_bounds_start = gtk_util::MirroredLeftPointForRect(
attached_tabstrip_->widget(),
dragged_bounds);
int dragged_bounds_end = gtk_util::MirroredRightPointForRect(
attached_tabstrip_->widget(),
dragged_bounds);
int right_tab_x = 0;
int index = -1;
for (int i = 0; i < attached_tabstrip_->GetTabCount(); i++) {
gfx::Rect ideal_bounds = attached_tabstrip_->GetIdealBounds(i);
gfx::Rect left_half, right_half;
ideal_bounds.SplitVertically(&left_half, &right_half);
right_tab_x = right_half.x();
if (dragged_bounds_start >= right_half.x() &&
dragged_bounds_start < right_half.right()) {
index = i + 1;
break;
} else if (dragged_bounds_start >= left_half.x() &&
dragged_bounds_start < left_half.right()) {
index = i;
break;
}
}
if (index == -1) {
if (dragged_bounds_end > right_tab_x)
index = attached_tabstrip_->GetTabCount();
else
index = 0;
}
TabGtk* tab = GetTabMatchingDraggedContents(
attached_tabstrip_, drag_data_->GetSourceWebContents());
if (tab == NULL) {
return index;
}
int max_index =
attached_tabstrip_-> GetTabCount() - static_cast<int>(drag_data_->size());
return std::max(0, std::min(max_index, index));
}
gfx::Point DraggedTabControllerGtk::GetDraggedViewPoint(
const gfx::Point& screen_point) {
int x = screen_point.x() -
dragged_view_->GetWidthInTabStripUpToMousePointer();
int y = screen_point.y() - mouse_offset_.y();
if (attached_tabstrip_) {
gfx::Rect tabstrip_bounds =
ui::GetWidgetScreenBounds(attached_tabstrip_->tabstrip_.get());
if (x < tabstrip_bounds.x() && screen_point.x() >= tabstrip_bounds.x())
x = tabstrip_bounds.x();
gfx::Size tab_size = dragged_view_->attached_tab_size();
int vertical_drag_magnetism = tab_size.height() * 2;
int vertical_detach_point = tabstrip_bounds.y() - vertical_drag_magnetism;
if (y < tabstrip_bounds.y() && screen_point.y() >= vertical_detach_point)
y = tabstrip_bounds.y();
int max_x =
tabstrip_bounds.right() - dragged_view_->GetTotalWidthInTabStrip();
int max_y = tabstrip_bounds.bottom() - tab_size.height();
if (x > max_x && screen_point.x() <= tabstrip_bounds.right())
x = max_x;
if (y > max_y && screen_point.y() <=
(tabstrip_bounds.bottom() + vertical_drag_magnetism)) {
y = max_y;
}
}
return gfx::Point(x, y);
}
int DraggedTabControllerGtk::NormalizeIndexToAttachedTabStrip(int index) const {
if (index >= attached_tabstrip_->model_->count())
return attached_tabstrip_->model_->count() - 1;
if (index == TabStripModel::kNoTab)
return 0;
return index;
}
TabGtk* DraggedTabControllerGtk::GetTabMatchingDraggedContents(
TabStripGtk* tabstrip, WebContents* web_contents) {
int index = tabstrip->model()->GetIndexOfWebContents(web_contents);
return index == TabStripModel::kNoTab ? NULL : tabstrip->GetTabAt(index);
}
std::vector<TabGtk*> DraggedTabControllerGtk::GetTabsMatchingDraggedContents(
TabStripGtk* tabstrip) {
std::vector<TabGtk*> dragged_tabs;
for (size_t i = 0; i < drag_data_->size(); ++i) {
if (!drag_data_->get(i)->contents_)
continue;
TabGtk* tab = GetTabMatchingDraggedContents(tabstrip,
drag_data_->get(i)->contents_);
if (tab)
dragged_tabs.push_back(tab);
}
return dragged_tabs;
}
void DraggedTabControllerGtk::SetDraggedTabsVisible(bool visible,
bool repaint) {
std::vector<TabGtk*> dragged_tabs(GetTabsMatchingDraggedContents(
attached_tabstrip_));
for (size_t i = 0; i < dragged_tabs.size(); ++i) {
dragged_tabs[i]->SetVisible(visible);
dragged_tabs[i]->set_dragging(!visible);
if (repaint)
dragged_tabs[i]->SchedulePaint();
}
}
bool DraggedTabControllerGtk::EndDragImpl(EndDragType type) {
bring_to_front_timer_.Stop();
bool destroy_now = true;
if (type != TAB_DESTROYED) {
if (dragged_view_.get()) {
if (type == CANCELED) {
RevertDrag();
} else {
destroy_now = CompleteDrag();
}
}
} else if (drag_data_->size() > 0) {
RevertDrag();
}
ResetDelegates();
if (destroy_now)
source_tabstrip_->DestroyDragController();
return destroy_now;
}
void DraggedTabControllerGtk::RevertDrag() {
bool restore_window = attached_tabstrip_ != source_tabstrip_;
if (attached_tabstrip_) {
if (attached_tabstrip_ != source_tabstrip_) {
for (size_t i = 0; i < drag_data_->size(); ++i) {
if (!drag_data_->get(i)->contents_)
continue;
int index = attached_tabstrip_->model()->GetIndexOfWebContents(
drag_data_->get(i)->contents_);
attached_tabstrip_->model()->DetachWebContentsAt(index);
}
attached_tabstrip_ = source_tabstrip_;
for (size_t i = 0; i < drag_data_->size(); ++i) {
if (!drag_data_->get(i)->contents_)
continue;
attached_tabstrip_->model()->InsertWebContentsAt(
drag_data_->get(i)->source_model_index_,
drag_data_->get(i)->contents_,
drag_data_->GetAddTypesForDraggedTabAt(i));
}
} else {
for (size_t i = 0; i < drag_data_->size(); ++i) {
if (!drag_data_->get(i)->contents_)
continue;
int index = attached_tabstrip_->model()->GetIndexOfWebContents(
drag_data_->get(i)->contents_);
source_tabstrip_->model()->MoveWebContentsAt(
index, drag_data_->get(i)->source_model_index_, true);
}
}
} else {
attached_tabstrip_ = source_tabstrip_;
for (size_t i = 0; i < drag_data_->size(); ++i) {
if (!drag_data_->get(i)->contents_)
continue;
source_tabstrip_->model()->InsertWebContentsAt(
drag_data_->get(i)->source_model_index_,
drag_data_->get(i)->contents_,
drag_data_->GetAddTypesForDraggedTabAt(i));
}
}
RestoreSelection(source_tabstrip_->model());
if (restore_window)
ShowWindow();
SetDraggedTabsVisible(true, false);
}
bool DraggedTabControllerGtk::CompleteDrag() {
bool destroy_immediately = true;
if (attached_tabstrip_) {
dragged_view_->AnimateToBounds(GetAnimateBounds(),
base::Bind(&DraggedTabControllerGtk::OnAnimateToBoundsComplete,
base::Unretained(this)));
destroy_immediately = false;
} else {
BrowserWindowGtk* window = source_tabstrip_->window();
gfx::Rect window_bounds = window->GetRestoredBounds();
window_bounds.set_origin(GetWindowCreatePoint());
std::vector<TabStripModelDelegate::NewStripContents> contentses;
for (size_t i = 0; i < drag_data_->size(); ++i) {
TabStripModelDelegate::NewStripContents item;
item.web_contents = drag_data_->get(i)->contents_;
item.add_types = drag_data_->GetAddTypesForDraggedTabAt(i);
contentses.push_back(item);
};
Browser* new_browser =
source_tabstrip_->model()->delegate()->CreateNewStripWithContents(
contentses, window_bounds, window->IsMaximized());
RestoreSelection(new_browser->tab_strip_model());
new_browser->window()->Show();
CleanUpHiddenFrame();
}
return destroy_immediately;
}
void DraggedTabControllerGtk::ResetDelegates() {
for (size_t i = 0; i < drag_data_->size(); ++i) {
if (drag_data_->get(i)->contents_ &&
drag_data_->get(i)->contents_->GetDelegate() == this) {
drag_data_->get(i)->ResetDelegate();
}
}
}
void DraggedTabControllerGtk::EnsureDraggedView() {
if (!dragged_view_.get()) {
gfx::Rect rect;
drag_data_->GetSourceWebContents()->GetView()->GetContainerBounds(&rect);
dragged_view_.reset(new DraggedViewGtk(drag_data_.get(), mouse_offset_,
rect.size()));
}
}
gfx::Rect DraggedTabControllerGtk::GetAnimateBounds() {
std::vector<TabGtk*> tabs = GetTabsMatchingDraggedContents(
attached_tabstrip_);
TabGtk* tab = !base::i18n::IsRTL() ? tabs.front() : tabs.back();
gfx::Rect bounds = tab->GetRequisition();
GtkWidget* widget = tab->widget();
GtkWidget* parent = gtk_widget_get_parent(widget);
bounds.Offset(ui::GetWidgetScreenOffset(parent));
return gfx::Rect(bounds.x(), bounds.y(),
dragged_view_->GetTotalWidthInTabStrip(), bounds.height());
}
void DraggedTabControllerGtk::HideWindow() {
GtkWidget* tabstrip = source_tabstrip_->widget();
GtkWindow* window = platform_util::GetTopLevel(tabstrip);
gtk_widget_hide(GTK_WIDGET(window));
}
void DraggedTabControllerGtk::ShowWindow() {
GtkWidget* tabstrip = source_tabstrip_->widget();
GtkWindow* window = platform_util::GetTopLevel(tabstrip);
gtk_window_present(window);
}
void DraggedTabControllerGtk::CleanUpHiddenFrame() {
if (source_tabstrip_->model()->empty())
source_tabstrip_->model()->delegate()->CloseFrameAfterDragSession();
}
void DraggedTabControllerGtk::CleanUpDraggedTabs() {
if (attached_tabstrip_ != source_tabstrip_) {
for (size_t i = 0; i < drag_data_->size(); ++i) {
if (drag_data_->get(i)->contents_) {
registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
content::Source<WebContents>(drag_data_->get(i)->contents_));
}
source_tabstrip_->DestroyDraggedTab(drag_data_->get(i)->tab_);
drag_data_->get(i)->tab_ = NULL;
}
}
}
void DraggedTabControllerGtk::OnAnimateToBoundsComplete() {
if (attached_tabstrip_)
SetDraggedTabsVisible(true, true);
CleanUpHiddenFrame();
if (!in_destructor_)
source_tabstrip_->DestroyDragController();
}
void DraggedTabControllerGtk::BringWindowUnderMouseToFront() {
gfx::NativeWindow window = GetLocalProcessWindow(
gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
if (window)
gtk_window_present(GTK_WINDOW(window));
}
bool DraggedTabControllerGtk::AreTabsConsecutive() {
for (size_t i = 1; i < drag_data_->size(); ++i) {
if (drag_data_->get(i - 1)->source_model_index_ + 1 !=
drag_data_->get(i)->source_model_index_) {
return false;
}
}
return true;
}
gfx::NativeWindow DraggedTabControllerGtk::GetLocalProcessWindow(
const gfx::Point& screen_point) {
std::set<GtkWidget*> dragged_window;
dragged_window.insert(dragged_view_->widget());
return GetLocalProcessWindowAtPoint(
gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(),
dragged_window);
}