| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" | 5 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "ash/accelerators/accelerator_commands.h" | 10 #include "ash/accelerators/accelerator_commands.h" |
| 11 #include "ash/wm/coordinate_conversion.h" | 11 #include "ash/wm/coordinate_conversion.h" |
| 12 #include "ash/wm/window_state.h" | 12 #include "ash/wm/window_state.h" |
| 13 #include "base/auto_reset.h" | 13 #include "base/auto_reset.h" |
| 14 #include "base/callback.h" | 14 #include "base/callback.h" |
| 15 #include "base/command_line.h" | |
| 16 #include "base/i18n/rtl.h" | 15 #include "base/i18n/rtl.h" |
| 17 #include "chrome/browser/chrome_notification_types.h" | 16 #include "chrome/browser/chrome_notification_types.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.h" | |
| 20 #include "chrome/browser/ui/browser_list.h" | 18 #include "chrome/browser/ui/browser_list.h" |
| 21 #include "chrome/browser/ui/browser_window.h" | 19 #include "chrome/browser/ui/browser_window.h" |
| 22 #include "chrome/browser/ui/media_utils.h" | |
| 23 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 20 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 24 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" | 21 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" |
| 25 #include "chrome/browser/ui/views/frame/browser_view.h" | 22 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 26 #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h" | 23 #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h" |
| 27 #include "chrome/browser/ui/views/tabs/stacked_tab_strip_layout.h" | 24 #include "chrome/browser/ui/views/tabs/stacked_tab_strip_layout.h" |
| 28 #include "chrome/browser/ui/views/tabs/tab.h" | 25 #include "chrome/browser/ui/views/tabs/tab.h" |
| 29 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 26 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
| 30 #include "chrome/browser/ui/views/tabs/window_finder.h" | 27 #include "chrome/browser/ui/views/tabs/window_finder.h" |
| 31 #include "chrome/common/chrome_switches.h" | |
| 32 #include "content/public/browser/invalidate_type.h" | |
| 33 #include "content/public/browser/notification_details.h" | 28 #include "content/public/browser/notification_details.h" |
| 34 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
| 35 #include "content/public/browser/notification_source.h" | 30 #include "content/public/browser/notification_source.h" |
| 36 #include "content/public/browser/notification_types.h" | 31 #include "content/public/browser/notification_types.h" |
| 37 #include "content/public/browser/user_metrics.h" | 32 #include "content/public/browser/user_metrics.h" |
| 38 #include "content/public/browser/web_contents.h" | 33 #include "content/public/browser/web_contents.h" |
| 39 #include "extensions/browser/extension_function_dispatcher.h" | 34 #include "extensions/browser/extension_function_dispatcher.h" |
| 40 #include "ui/aura/env.h" | 35 #include "ui/aura/env.h" |
| 41 #include "ui/aura/env.h" | |
| 42 #include "ui/aura/window.h" | 36 #include "ui/aura/window.h" |
| 43 #include "ui/aura/window_event_dispatcher.h" | |
| 44 #include "ui/base/resource/resource_bundle.h" | |
| 45 #include "ui/events/event_constants.h" | 37 #include "ui/events/event_constants.h" |
| 46 #include "ui/events/event_utils.h" | |
| 47 #include "ui/events/gestures/gesture_recognizer.h" | 38 #include "ui/events/gestures/gesture_recognizer.h" |
| 48 #include "ui/gfx/geometry/point_conversions.h" | 39 #include "ui/gfx/geometry/point_conversions.h" |
| 49 #include "ui/gfx/screen.h" | 40 #include "ui/gfx/screen.h" |
| 50 #include "ui/views/focus/view_storage.h" | 41 #include "ui/views/focus/view_storage.h" |
| 51 #include "ui/views/widget/root_view.h" | 42 #include "ui/views/widget/root_view.h" |
| 52 #include "ui/views/widget/widget.h" | 43 #include "ui/views/widget/widget.h" |
| 53 #include "ui/wm/core/window_modality_controller.h" | 44 #include "ui/wm/core/window_modality_controller.h" |
| 54 | 45 |
| 55 #if defined(OS_WIN) | |
| 56 #include "ui/aura/window.h" | |
| 57 #include "ui/events/gestures/gesture_recognizer.h" | |
| 58 #endif | |
| 59 | |
| 60 using base::UserMetricsAction; | 46 using base::UserMetricsAction; |
| 61 using content::OpenURLParams; | 47 using content::OpenURLParams; |
| 62 using content::WebContents; | 48 using content::WebContents; |
| 63 | 49 |
| 64 // If non-null there is a drag underway. | 50 // If non-null there is a drag underway. |
| 65 static TabDragController* instance_ = NULL; | 51 static TabDragController* instance_ = NULL; |
| 66 | 52 |
| 67 namespace { | 53 namespace { |
| 68 | 54 |
| 69 // Delay, in ms, during dragging before we bring a window to front. | 55 // Delay, in ms, during dragging before we bring a window to front. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 | 137 |
| 152 base::Closure escape_callback_; | 138 base::Closure escape_callback_; |
| 153 | 139 |
| 154 DISALLOW_COPY_AND_ASSIGN(EscapeTracker); | 140 DISALLOW_COPY_AND_ASSIGN(EscapeTracker); |
| 155 }; | 141 }; |
| 156 | 142 |
| 157 } // namespace | 143 } // namespace |
| 158 | 144 |
| 159 TabDragController::TabDragData::TabDragData() | 145 TabDragController::TabDragData::TabDragData() |
| 160 : contents(NULL), | 146 : contents(NULL), |
| 161 original_delegate(NULL), | |
| 162 source_model_index(-1), | 147 source_model_index(-1), |
| 163 attached_tab(NULL), | 148 attached_tab(NULL), |
| 164 pinned(false) { | 149 pinned(false) { |
| 165 } | 150 } |
| 166 | 151 |
| 167 TabDragController::TabDragData::~TabDragData() { | 152 TabDragController::TabDragData::~TabDragData() { |
| 168 } | 153 } |
| 169 | 154 |
| 170 /////////////////////////////////////////////////////////////////////////////// | 155 /////////////////////////////////////////////////////////////////////////////// |
| 171 // TabDragController, public: | 156 // TabDragController, public: |
| 172 | 157 |
| 173 // static | 158 // static |
| 174 const int TabDragController::kTouchVerticalDetachMagnetism = 50; | 159 const int TabDragController::kTouchVerticalDetachMagnetism = 50; |
| 175 | 160 |
| 176 // static | 161 // static |
| 177 const int TabDragController::kVerticalDetachMagnetism = 15; | 162 const int TabDragController::kVerticalDetachMagnetism = 15; |
| 178 | 163 |
| 179 TabDragController::TabDragController() | 164 TabDragController::TabDragController() |
| 180 : detach_into_browser_(true), | 165 : event_source_(EVENT_SOURCE_MOUSE), |
| 181 event_source_(EVENT_SOURCE_MOUSE), | |
| 182 source_tabstrip_(NULL), | 166 source_tabstrip_(NULL), |
| 183 attached_tabstrip_(NULL), | 167 attached_tabstrip_(NULL), |
| 184 screen_(NULL), | 168 screen_(NULL), |
| 185 host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE), | 169 host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE), |
| 186 use_aura_capture_policy_(false), | 170 use_aura_capture_policy_(false), |
| 187 offset_to_width_ratio_(0), | 171 offset_to_width_ratio_(0), |
| 188 old_focused_view_id_( | 172 old_focused_view_id_( |
| 189 views::ViewStorage::GetInstance()->CreateStorageID()), | 173 views::ViewStorage::GetInstance()->CreateStorageID()), |
| 190 last_move_screen_loc_(0), | 174 last_move_screen_loc_(0), |
| 191 started_drag_(false), | 175 started_drag_(false), |
| 192 active_(true), | 176 active_(true), |
| 193 source_tab_index_(std::numeric_limits<size_t>::max()), | 177 source_tab_index_(std::numeric_limits<size_t>::max()), |
| 194 initial_move_(true), | 178 initial_move_(true), |
| 195 detach_behavior_(DETACHABLE), | |
| 196 move_behavior_(REORDER), | 179 move_behavior_(REORDER), |
| 197 mouse_move_direction_(0), | 180 mouse_move_direction_(0), |
| 198 is_dragging_window_(false), | 181 is_dragging_window_(false), |
| 199 is_dragging_new_browser_(false), | 182 is_dragging_new_browser_(false), |
| 200 was_source_maximized_(false), | 183 was_source_maximized_(false), |
| 201 was_source_fullscreen_(false), | 184 was_source_fullscreen_(false), |
| 202 did_restore_window_(false), | 185 did_restore_window_(false), |
| 203 end_run_loop_behavior_(END_RUN_LOOP_STOP_DRAGGING), | 186 end_run_loop_behavior_(END_RUN_LOOP_STOP_DRAGGING), |
| 204 waiting_for_run_loop_to_exit_(false), | 187 waiting_for_run_loop_to_exit_(false), |
| 205 tab_strip_to_attach_to_after_exit_(NULL), | 188 tab_strip_to_attach_to_after_exit_(NULL), |
| 206 move_loop_widget_(NULL), | 189 move_loop_widget_(NULL), |
| 207 is_mutating_(false), | 190 is_mutating_(false), |
| 208 attach_x_(-1), | 191 attach_x_(-1), |
| 209 attach_index_(-1), | 192 attach_index_(-1), |
| 210 weak_factory_(this) { | 193 weak_factory_(this) { |
| 211 instance_ = this; | 194 instance_ = this; |
| 212 } | 195 } |
| 213 | 196 |
| 214 TabDragController::~TabDragController() { | 197 TabDragController::~TabDragController() { |
| 215 views::ViewStorage::GetInstance()->RemoveView(old_focused_view_id_); | 198 views::ViewStorage::GetInstance()->RemoveView(old_focused_view_id_); |
| 216 | 199 |
| 217 if (instance_ == this) | 200 if (instance_ == this) |
| 218 instance_ = NULL; | 201 instance_ = NULL; |
| 219 | 202 |
| 220 if (move_loop_widget_) { | 203 if (move_loop_widget_) { |
| 221 move_loop_widget_->RemoveObserver(this); | 204 move_loop_widget_->RemoveObserver(this); |
| 222 SetWindowPositionManaged(move_loop_widget_->GetNativeView(), true); | 205 SetWindowPositionManaged(move_loop_widget_->GetNativeView(), true); |
| 223 } | 206 } |
| 224 | 207 |
| 225 if (source_tabstrip_ && detach_into_browser_) | 208 if (source_tabstrip_) |
| 226 GetModel(source_tabstrip_)->RemoveObserver(this); | 209 GetModel(source_tabstrip_)->RemoveObserver(this); |
| 227 | 210 |
| 228 // Reset the delegate of the dragged WebContents. This ends up doing nothing | |
| 229 // if the drag was completed. | |
| 230 if (!detach_into_browser_) | |
| 231 ResetDelegates(); | |
| 232 | |
| 233 if (event_source_ == EVENT_SOURCE_TOUCH) { | 211 if (event_source_ == EVENT_SOURCE_TOUCH) { |
| 234 TabStrip* capture_tabstrip = (attached_tabstrip_ && detach_into_browser_) ? | 212 TabStrip* capture_tabstrip = attached_tabstrip_ ? |
| 235 attached_tabstrip_ : source_tabstrip_; | 213 attached_tabstrip_ : source_tabstrip_; |
| 236 capture_tabstrip->GetWidget()->ReleaseCapture(); | 214 capture_tabstrip->GetWidget()->ReleaseCapture(); |
| 237 } | 215 } |
| 238 } | 216 } |
| 239 | 217 |
| 240 void TabDragController::Init( | 218 void TabDragController::Init( |
| 241 TabStrip* source_tabstrip, | 219 TabStrip* source_tabstrip, |
| 242 Tab* source_tab, | 220 Tab* source_tab, |
| 243 const std::vector<Tab*>& tabs, | 221 const std::vector<Tab*>& tabs, |
| 244 const gfx::Point& mouse_offset, | 222 const gfx::Point& mouse_offset, |
| 245 int source_tab_offset, | 223 int source_tab_offset, |
| 246 const ui::ListSelectionModel& initial_selection_model, | 224 const ui::ListSelectionModel& initial_selection_model, |
| 247 DetachBehavior detach_behavior, | |
| 248 MoveBehavior move_behavior, | 225 MoveBehavior move_behavior, |
| 249 EventSource event_source) { | 226 EventSource event_source) { |
| 250 DCHECK(!tabs.empty()); | 227 DCHECK(!tabs.empty()); |
| 251 DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end()); | 228 DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end()); |
| 252 source_tabstrip_ = source_tabstrip; | 229 source_tabstrip_ = source_tabstrip; |
| 253 was_source_maximized_ = source_tabstrip->GetWidget()->IsMaximized(); | 230 was_source_maximized_ = source_tabstrip->GetWidget()->IsMaximized(); |
| 254 was_source_fullscreen_ = source_tabstrip->GetWidget()->IsFullscreen(); | 231 was_source_fullscreen_ = source_tabstrip->GetWidget()->IsFullscreen(); |
| 255 screen_ = gfx::Screen::GetScreenFor( | 232 screen_ = gfx::Screen::GetScreenFor( |
| 256 source_tabstrip->GetWidget()->GetNativeView()); | 233 source_tabstrip->GetWidget()->GetNativeView()); |
| 257 host_desktop_type_ = chrome::GetHostDesktopTypeForNativeView( | 234 host_desktop_type_ = chrome::GetHostDesktopTypeForNativeView( |
| 258 source_tabstrip->GetWidget()->GetNativeView()); | 235 source_tabstrip->GetWidget()->GetNativeView()); |
| 259 #if defined(OS_LINUX) | 236 #if defined(OS_LINUX) |
| 260 use_aura_capture_policy_ = true; | 237 use_aura_capture_policy_ = true; |
| 261 #else | 238 #else |
| 262 use_aura_capture_policy_ = | 239 use_aura_capture_policy_ = |
| 263 (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH); | 240 (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH); |
| 264 #endif | 241 #endif |
| 265 start_point_in_screen_ = gfx::Point(source_tab_offset, mouse_offset.y()); | 242 start_point_in_screen_ = gfx::Point(source_tab_offset, mouse_offset.y()); |
| 266 views::View::ConvertPointToScreen(source_tab, &start_point_in_screen_); | 243 views::View::ConvertPointToScreen(source_tab, &start_point_in_screen_); |
| 267 event_source_ = event_source; | 244 event_source_ = event_source; |
| 268 mouse_offset_ = mouse_offset; | 245 mouse_offset_ = mouse_offset; |
| 269 detach_behavior_ = detach_behavior; | |
| 270 move_behavior_ = move_behavior; | 246 move_behavior_ = move_behavior; |
| 271 last_point_in_screen_ = start_point_in_screen_; | 247 last_point_in_screen_ = start_point_in_screen_; |
| 272 last_move_screen_loc_ = start_point_in_screen_.x(); | 248 last_move_screen_loc_ = start_point_in_screen_.x(); |
| 273 initial_tab_positions_ = source_tabstrip->GetTabXCoordinates(); | 249 initial_tab_positions_ = source_tabstrip->GetTabXCoordinates(); |
| 274 if (detach_behavior == NOT_DETACHABLE) | |
| 275 detach_into_browser_ = false; | |
| 276 | 250 |
| 277 if (detach_into_browser_) | 251 GetModel(source_tabstrip_)->AddObserver(this); |
| 278 GetModel(source_tabstrip_)->AddObserver(this); | |
| 279 | 252 |
| 280 drag_data_.resize(tabs.size()); | 253 drag_data_.resize(tabs.size()); |
| 281 for (size_t i = 0; i < tabs.size(); ++i) | 254 for (size_t i = 0; i < tabs.size(); ++i) |
| 282 InitTabDragData(tabs[i], &(drag_data_[i])); | 255 InitTabDragData(tabs[i], &(drag_data_[i])); |
| 283 source_tab_index_ = | 256 source_tab_index_ = |
| 284 std::find(tabs.begin(), tabs.end(), source_tab) - tabs.begin(); | 257 std::find(tabs.begin(), tabs.end(), source_tab) - tabs.begin(); |
| 285 | 258 |
| 286 // Listen for Esc key presses. | 259 // Listen for Esc key presses. |
| 287 escape_tracker_.reset( | 260 escape_tracker_.reset( |
| 288 new EscapeTracker(base::Bind(&TabDragController::EndDrag, | 261 new EscapeTracker(base::Bind(&TabDragController::EndDrag, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 | 310 |
| 338 // On windows SaveFocus() may trigger a capture lost, which destroys us. | 311 // On windows SaveFocus() may trigger a capture lost, which destroys us. |
| 339 { | 312 { |
| 340 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); | 313 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); |
| 341 SaveFocus(); | 314 SaveFocus(); |
| 342 if (!ref) | 315 if (!ref) |
| 343 return; | 316 return; |
| 344 } | 317 } |
| 345 started_drag_ = true; | 318 started_drag_ = true; |
| 346 Attach(source_tabstrip_, gfx::Point()); | 319 Attach(source_tabstrip_, gfx::Point()); |
| 347 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) == | 320 if (static_cast<int>(drag_data_.size()) == |
| 348 GetModel(source_tabstrip_)->count()) { | 321 GetModel(source_tabstrip_)->count()) { |
| 349 if (was_source_maximized_ || was_source_fullscreen_) { | 322 if (was_source_maximized_ || was_source_fullscreen_) { |
| 350 did_restore_window_ = true; | 323 did_restore_window_ = true; |
| 351 // When all tabs in a maximized browser are dragged the browser gets | 324 // When all tabs in a maximized browser are dragged the browser gets |
| 352 // restored during the drag and maximized back when the drag ends. | 325 // restored during the drag and maximized back when the drag ends. |
| 353 views::Widget* widget = GetAttachedBrowserWidget(); | 326 views::Widget* widget = GetAttachedBrowserWidget(); |
| 354 const int last_tabstrip_width = attached_tabstrip_->tab_area_width(); | 327 const int last_tabstrip_width = attached_tabstrip_->tab_area_width(); |
| 355 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs(); | 328 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs(); |
| 356 OffsetX(GetAttachedDragPoint(point_in_screen).x(), &drag_bounds); | 329 OffsetX(GetAttachedDragPoint(point_in_screen).x(), &drag_bounds); |
| 357 gfx::Rect new_bounds(CalculateDraggedBrowserBounds(source_tabstrip_, | 330 gfx::Rect new_bounds(CalculateDraggedBrowserBounds(source_tabstrip_, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 TRACE_EVENT0("views", "TabDragController::InitTabDragData"); | 366 TRACE_EVENT0("views", "TabDragController::InitTabDragData"); |
| 394 drag_data->source_model_index = | 367 drag_data->source_model_index = |
| 395 source_tabstrip_->GetModelIndexOfTab(tab); | 368 source_tabstrip_->GetModelIndexOfTab(tab); |
| 396 drag_data->contents = GetModel(source_tabstrip_)->GetWebContentsAt( | 369 drag_data->contents = GetModel(source_tabstrip_)->GetWebContentsAt( |
| 397 drag_data->source_model_index); | 370 drag_data->source_model_index); |
| 398 drag_data->pinned = source_tabstrip_->IsTabPinned(tab); | 371 drag_data->pinned = source_tabstrip_->IsTabPinned(tab); |
| 399 registrar_.Add( | 372 registrar_.Add( |
| 400 this, | 373 this, |
| 401 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 374 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| 402 content::Source<WebContents>(drag_data->contents)); | 375 content::Source<WebContents>(drag_data->contents)); |
| 403 | |
| 404 if (!detach_into_browser_) { | |
| 405 drag_data->original_delegate = drag_data->contents->GetDelegate(); | |
| 406 drag_data->contents->SetDelegate(this); | |
| 407 } | |
| 408 } | 376 } |
| 409 | 377 |
| 410 /////////////////////////////////////////////////////////////////////////////// | 378 /////////////////////////////////////////////////////////////////////////////// |
| 411 // TabDragController, PageNavigator implementation: | |
| 412 | |
| 413 WebContents* TabDragController::OpenURLFromTab( | |
| 414 WebContents* source, | |
| 415 const OpenURLParams& params) { | |
| 416 if (source_tab_drag_data()->original_delegate) { | |
| 417 OpenURLParams forward_params = params; | |
| 418 if (params.disposition == CURRENT_TAB) | |
| 419 forward_params.disposition = NEW_WINDOW; | |
| 420 | |
| 421 return source_tab_drag_data()->original_delegate->OpenURLFromTab( | |
| 422 source, forward_params); | |
| 423 } | |
| 424 return NULL; | |
| 425 } | |
| 426 | |
| 427 /////////////////////////////////////////////////////////////////////////////// | |
| 428 // TabDragController, content::WebContentsDelegate implementation: | |
| 429 | |
| 430 void TabDragController::NavigationStateChanged(const WebContents* source, | |
| 431 unsigned changed_flags) { | |
| 432 if (attached_tabstrip_ || | |
| 433 changed_flags == content::INVALIDATE_TYPE_PAGE_ACTIONS) { | |
| 434 for (size_t i = 0; i < drag_data_.size(); ++i) { | |
| 435 if (drag_data_[i].contents == source) { | |
| 436 // Pass the NavigationStateChanged call to the original delegate so | |
| 437 // that the title is updated. Do this only when we are attached as | |
| 438 // otherwise the Tab isn't in the TabStrip (except for page action | |
| 439 // updates). | |
| 440 drag_data_[i].original_delegate->NavigationStateChanged(source, | |
| 441 changed_flags); | |
| 442 break; | |
| 443 } | |
| 444 } | |
| 445 } | |
| 446 } | |
| 447 | |
| 448 void TabDragController::AddNewContents(WebContents* source, | |
| 449 WebContents* new_contents, | |
| 450 WindowOpenDisposition disposition, | |
| 451 const gfx::Rect& initial_pos, | |
| 452 bool user_gesture, | |
| 453 bool* was_blocked) { | |
| 454 DCHECK_NE(CURRENT_TAB, disposition); | |
| 455 | |
| 456 // Theoretically could be called while dragging if the page tries to | |
| 457 // spawn a window. Route this message back to the browser in most cases. | |
| 458 if (source_tab_drag_data()->original_delegate) { | |
| 459 source_tab_drag_data()->original_delegate->AddNewContents( | |
| 460 source, new_contents, disposition, initial_pos, user_gesture, | |
| 461 was_blocked); | |
| 462 } | |
| 463 } | |
| 464 | |
| 465 bool TabDragController::ShouldSuppressDialogs() { | |
| 466 // When a dialog is about to be shown we revert the drag. Otherwise a modal | |
| 467 // dialog might appear and attempt to parent itself to a hidden tabcontents. | |
| 468 EndDragImpl(CANCELED); | |
| 469 return false; | |
| 470 } | |
| 471 | |
| 472 content::JavaScriptDialogManager* | |
| 473 TabDragController::GetJavaScriptDialogManager() { | |
| 474 return GetJavaScriptDialogManagerInstance(); | |
| 475 } | |
| 476 | |
| 477 void TabDragController::RequestMediaAccessPermission( | |
| 478 content::WebContents* web_contents, | |
| 479 const content::MediaStreamRequest& request, | |
| 480 const content::MediaResponseCallback& callback) { | |
| 481 ::RequestMediaAccessPermission( | |
| 482 web_contents, | |
| 483 Profile::FromBrowserContext(web_contents->GetBrowserContext()), | |
| 484 request, | |
| 485 callback); | |
| 486 } | |
| 487 | |
| 488 /////////////////////////////////////////////////////////////////////////////// | |
| 489 // TabDragController, content::NotificationObserver implementation: | 379 // TabDragController, content::NotificationObserver implementation: |
| 490 | 380 |
| 491 void TabDragController::Observe( | 381 void TabDragController::Observe( |
| 492 int type, | 382 int type, |
| 493 const content::NotificationSource& source, | 383 const content::NotificationSource& source, |
| 494 const content::NotificationDetails& details) { | 384 const content::NotificationDetails& details) { |
| 495 DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type); | 385 DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type); |
| 496 WebContents* destroyed_web_contents = | 386 WebContents* destroyed_web_contents = |
| 497 content::Source<WebContents>(source).ptr(); | 387 content::Source<WebContents>(source).ptr(); |
| 498 for (size_t i = 0; i < drag_data_.size(); ++i) { | 388 for (size_t i = 0; i < drag_data_.size(); ++i) { |
| 499 if (drag_data_[i].contents == destroyed_web_contents) { | 389 if (drag_data_[i].contents == destroyed_web_contents) { |
| 500 // One of the tabs we're dragging has been destroyed. Cancel the drag. | 390 // One of the tabs we're dragging has been destroyed. Cancel the drag. |
| 501 if (destroyed_web_contents->GetDelegate() == this) | |
| 502 destroyed_web_contents->SetDelegate(NULL); | |
| 503 drag_data_[i].contents = NULL; | 391 drag_data_[i].contents = NULL; |
| 504 drag_data_[i].original_delegate = NULL; | |
| 505 EndDragImpl(TAB_DESTROYED); | 392 EndDragImpl(TAB_DESTROYED); |
| 506 return; | 393 return; |
| 507 } | 394 } |
| 508 } | 395 } |
| 509 // If we get here it means we got notification for a tab we don't know about. | 396 // If we get here it means we got notification for a tab we don't know about. |
| 510 NOTREACHED(); | 397 NOTREACHED(); |
| 511 } | 398 } |
| 512 | 399 |
| 513 void TabDragController::OnWidgetBoundsChanged(views::Widget* widget, | 400 void TabDragController::OnWidgetBoundsChanged(views::Widget* widget, |
| 514 const gfx::Rect& new_bounds) { | 401 const gfx::Rect& new_bounds) { |
| 515 TRACE_EVENT1("views", "TabDragController::OnWidgetBoundsChanged", | 402 TRACE_EVENT1("views", "TabDragController::OnWidgetBoundsChanged", |
| 516 "new_bounds", new_bounds.ToString()); | 403 "new_bounds", new_bounds.ToString()); |
| 517 | 404 |
| 518 Drag(GetCursorScreenPoint()); | 405 Drag(GetCursorScreenPoint()); |
| 519 } | 406 } |
| 520 | 407 |
| 521 void TabDragController::TabStripEmpty() { | 408 void TabDragController::TabStripEmpty() { |
| 522 DCHECK(detach_into_browser_); | |
| 523 GetModel(source_tabstrip_)->RemoveObserver(this); | 409 GetModel(source_tabstrip_)->RemoveObserver(this); |
| 524 // NULL out source_tabstrip_ so that we don't attempt to add back to it (in | 410 // NULL out source_tabstrip_ so that we don't attempt to add back to it (in |
| 525 // the case of a revert). | 411 // the case of a revert). |
| 526 source_tabstrip_ = NULL; | 412 source_tabstrip_ = NULL; |
| 527 } | 413 } |
| 528 | 414 |
| 529 /////////////////////////////////////////////////////////////////////////////// | 415 /////////////////////////////////////////////////////////////////////////////// |
| 530 // TabDragController, private: | 416 // TabDragController, private: |
| 531 | 417 |
| 532 void TabDragController::InitWindowCreatePoint() { | 418 void TabDragController::InitWindowCreatePoint() { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 int x_offset = abs(point_in_screen.x() - start_point_in_screen_.x()); | 483 int x_offset = abs(point_in_screen.x() - start_point_in_screen_.x()); |
| 598 int y_offset = abs(point_in_screen.y() - start_point_in_screen_.y()); | 484 int y_offset = abs(point_in_screen.y() - start_point_in_screen_.y()); |
| 599 return sqrt(pow(static_cast<float>(x_offset), 2) + | 485 return sqrt(pow(static_cast<float>(x_offset), 2) + |
| 600 pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance; | 486 pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance; |
| 601 } | 487 } |
| 602 | 488 |
| 603 void TabDragController::ContinueDragging(const gfx::Point& point_in_screen) { | 489 void TabDragController::ContinueDragging(const gfx::Point& point_in_screen) { |
| 604 TRACE_EVENT1("views", "TabDragController::ContinueDragging", | 490 TRACE_EVENT1("views", "TabDragController::ContinueDragging", |
| 605 "point_in_screen", point_in_screen.ToString()); | 491 "point_in_screen", point_in_screen.ToString()); |
| 606 | 492 |
| 607 DCHECK(!detach_into_browser_ || attached_tabstrip_); | 493 DCHECK(attached_tabstrip_); |
| 608 | 494 |
| 609 TabStrip* target_tabstrip = detach_behavior_ == DETACHABLE ? | 495 TabStrip* target_tabstrip = GetTargetTabStripForPoint(point_in_screen); |
| 610 GetTargetTabStripForPoint(point_in_screen) : source_tabstrip_; | |
| 611 bool tab_strip_changed = (target_tabstrip != attached_tabstrip_); | 496 bool tab_strip_changed = (target_tabstrip != attached_tabstrip_); |
| 612 | 497 |
| 613 if (attached_tabstrip_) { | 498 if (attached_tabstrip_) { |
| 614 int move_delta = point_in_screen.x() - last_point_in_screen_.x(); | 499 int move_delta = point_in_screen.x() - last_point_in_screen_.x(); |
| 615 if (move_delta > 0) | 500 if (move_delta > 0) |
| 616 mouse_move_direction_ |= kMovedMouseRight; | 501 mouse_move_direction_ |= kMovedMouseRight; |
| 617 else if (move_delta < 0) | 502 else if (move_delta < 0) |
| 618 mouse_move_direction_ |= kMovedMouseLeft; | 503 mouse_move_direction_ |= kMovedMouseLeft; |
| 619 } | 504 } |
| 620 last_point_in_screen_ = point_in_screen; | 505 last_point_in_screen_ = point_in_screen; |
| 621 | 506 |
| 622 if (tab_strip_changed) { | 507 if (tab_strip_changed) { |
| 623 is_dragging_new_browser_ = false; | 508 is_dragging_new_browser_ = false; |
| 624 did_restore_window_ = false; | 509 did_restore_window_ = false; |
| 625 if (detach_into_browser_ && | 510 if (DragBrowserToNewTabStrip(target_tabstrip, point_in_screen) == |
| 626 DragBrowserToNewTabStrip(target_tabstrip, point_in_screen) == | |
| 627 DRAG_BROWSER_RESULT_STOP) { | 511 DRAG_BROWSER_RESULT_STOP) { |
| 628 return; | 512 return; |
| 629 } else if (!detach_into_browser_) { | |
| 630 if (attached_tabstrip_) | |
| 631 Detach(RELEASE_CAPTURE); | |
| 632 if (target_tabstrip) | |
| 633 Attach(target_tabstrip, point_in_screen); | |
| 634 } | 513 } |
| 635 } | 514 } |
| 636 if (is_dragging_window_) { | 515 if (is_dragging_window_) { |
| 637 static_cast<base::Timer*>(&bring_to_front_timer_)->Start(FROM_HERE, | 516 static_cast<base::Timer*>(&bring_to_front_timer_)->Start(FROM_HERE, |
| 638 base::TimeDelta::FromMilliseconds(kBringToFrontDelay), | 517 base::TimeDelta::FromMilliseconds(kBringToFrontDelay), |
| 639 base::Bind(&TabDragController::BringWindowUnderPointToFront, | 518 base::Bind(&TabDragController::BringWindowUnderPointToFront, |
| 640 base::Unretained(this), point_in_screen)); | 519 base::Unretained(this), point_in_screen)); |
| 641 } | 520 } |
| 642 | 521 |
| 643 if (!is_dragging_window_ && attached_tabstrip_) { | 522 if (!is_dragging_window_ && attached_tabstrip_) { |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 898 return DETACH_AFTER; | 777 return DETACH_AFTER; |
| 899 return DETACH_ABOVE_OR_BELOW; | 778 return DETACH_ABOVE_OR_BELOW; |
| 900 } | 779 } |
| 901 | 780 |
| 902 TabStrip* TabDragController::GetTargetTabStripForPoint( | 781 TabStrip* TabDragController::GetTargetTabStripForPoint( |
| 903 const gfx::Point& point_in_screen) { | 782 const gfx::Point& point_in_screen) { |
| 904 TRACE_EVENT1("views", "TabDragController::GetTargetTabStripForPoint", | 783 TRACE_EVENT1("views", "TabDragController::GetTargetTabStripForPoint", |
| 905 "point_in_screen", point_in_screen.ToString()); | 784 "point_in_screen", point_in_screen.ToString()); |
| 906 | 785 |
| 907 if (move_only() && attached_tabstrip_) { | 786 if (move_only() && attached_tabstrip_) { |
| 908 DCHECK_EQ(DETACHABLE, detach_behavior_); | |
| 909 // move_only() is intended for touch, in which case we only want to detach | 787 // move_only() is intended for touch, in which case we only want to detach |
| 910 // if the touch point moves significantly in the vertical distance. | 788 // if the touch point moves significantly in the vertical distance. |
| 911 gfx::Rect tabstrip_bounds = GetViewScreenBounds(attached_tabstrip_); | 789 gfx::Rect tabstrip_bounds = GetViewScreenBounds(attached_tabstrip_); |
| 912 if (DoesRectContainVerticalPointExpanded(tabstrip_bounds, | 790 if (DoesRectContainVerticalPointExpanded(tabstrip_bounds, |
| 913 kTouchVerticalDetachMagnetism, | 791 kTouchVerticalDetachMagnetism, |
| 914 point_in_screen.y())) | 792 point_in_screen.y())) |
| 915 return attached_tabstrip_; | 793 return attached_tabstrip_; |
| 916 } | 794 } |
| 917 gfx::NativeWindow local_window = | 795 gfx::NativeWindow local_window = |
| 918 GetLocalProcessWindow(point_in_screen, is_dragging_window_); | 796 GetLocalProcessWindow(point_in_screen, is_dragging_window_); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 | 850 |
| 973 std::vector<Tab*> tabs = | 851 std::vector<Tab*> tabs = |
| 974 GetTabsMatchingDraggedContents(attached_tabstrip_); | 852 GetTabsMatchingDraggedContents(attached_tabstrip_); |
| 975 | 853 |
| 976 if (tabs.empty()) { | 854 if (tabs.empty()) { |
| 977 // Transitioning from detached to attached to a new tabstrip. Add tabs to | 855 // Transitioning from detached to attached to a new tabstrip. Add tabs to |
| 978 // the new model. | 856 // the new model. |
| 979 | 857 |
| 980 selection_model_before_attach_.Copy(attached_tabstrip->GetSelectionModel()); | 858 selection_model_before_attach_.Copy(attached_tabstrip->GetSelectionModel()); |
| 981 | 859 |
| 982 if (!detach_into_browser_) { | |
| 983 // Remove ourselves as the delegate now that the dragged WebContents is | |
| 984 // being inserted back into a Browser. | |
| 985 for (size_t i = 0; i < drag_data_.size(); ++i) { | |
| 986 drag_data_[i].contents->SetDelegate(NULL); | |
| 987 drag_data_[i].original_delegate = NULL; | |
| 988 } | |
| 989 | |
| 990 // Return the WebContents to normalcy. | |
| 991 source_dragged_contents()->DecrementCapturerCount(); | |
| 992 } | |
| 993 | |
| 994 // Inserting counts as a move. We don't want the tabs to jitter when the | 860 // Inserting counts as a move. We don't want the tabs to jitter when the |
| 995 // user moves the tab immediately after attaching it. | 861 // user moves the tab immediately after attaching it. |
| 996 last_move_screen_loc_ = point_in_screen.x(); | 862 last_move_screen_loc_ = point_in_screen.x(); |
| 997 | 863 |
| 998 // Figure out where to insert the tab based on the bounds of the dragged | 864 // Figure out where to insert the tab based on the bounds of the dragged |
| 999 // representation and the ideal bounds of the other Tabs already in the | 865 // representation and the ideal bounds of the other Tabs already in the |
| 1000 // strip. ("ideal bounds" are stable even if the Tabs' actual bounds are | 866 // strip. ("ideal bounds" are stable even if the Tabs' actual bounds are |
| 1001 // changing due to animation). | 867 // changing due to animation). |
| 1002 gfx::Point tab_strip_point(point_in_screen); | 868 gfx::Point tab_strip_point(point_in_screen); |
| 1003 views::View::ConvertPointFromScreen(attached_tabstrip_, &tab_strip_point); | 869 views::View::ConvertPointFromScreen(attached_tabstrip_, &tab_strip_point); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 tabs_to_source.end()); | 906 tabs_to_source.end()); |
| 1041 int new_x = attached_tabstrip_->GetSizeNeededForTabs(tabs_to_source) - | 907 int new_x = attached_tabstrip_->GetSizeNeededForTabs(tabs_to_source) - |
| 1042 tabs[source_tab_index_]->width() + | 908 tabs[source_tab_index_]->width() + |
| 1043 static_cast<int>(offset_to_width_ratio_ * | 909 static_cast<int>(offset_to_width_ratio_ * |
| 1044 tabs[source_tab_index_]->width()); | 910 tabs[source_tab_index_]->width()); |
| 1045 mouse_offset_.set_x(new_x); | 911 mouse_offset_.set_x(new_x); |
| 1046 | 912 |
| 1047 // Transfer ownership of us to the new tabstrip as well as making sure the | 913 // Transfer ownership of us to the new tabstrip as well as making sure the |
| 1048 // window has capture. This is important so that if activation changes the | 914 // window has capture. This is important so that if activation changes the |
| 1049 // drag isn't prematurely canceled. | 915 // drag isn't prematurely canceled. |
| 1050 if (detach_into_browser_) { | 916 attached_tabstrip_->GetWidget()->SetCapture(attached_tabstrip_); |
| 1051 attached_tabstrip_->GetWidget()->SetCapture(attached_tabstrip_); | 917 attached_tabstrip_->OwnDragController(this); |
| 1052 attached_tabstrip_->OwnDragController(this); | |
| 1053 } | |
| 1054 | 918 |
| 1055 // Redirect all mouse events to the TabStrip so that the tab that originated | 919 // Redirect all mouse events to the TabStrip so that the tab that originated |
| 1056 // the drag can safely be deleted. | 920 // the drag can safely be deleted. |
| 1057 if (detach_into_browser_ || attached_tabstrip_ == source_tabstrip_) { | 921 static_cast<views::internal::RootView*>( |
| 1058 static_cast<views::internal::RootView*>( | 922 attached_tabstrip_->GetWidget()->GetRootView())->SetMouseHandler( |
| 1059 attached_tabstrip_->GetWidget()->GetRootView())->SetMouseHandler( | 923 attached_tabstrip_); |
| 1060 attached_tabstrip_); | |
| 1061 } | |
| 1062 } | 924 } |
| 1063 | 925 |
| 1064 void TabDragController::Detach(ReleaseCapture release_capture) { | 926 void TabDragController::Detach(ReleaseCapture release_capture) { |
| 1065 TRACE_EVENT1("views", "TabDragController::Detach", | 927 TRACE_EVENT1("views", "TabDragController::Detach", |
| 1066 "release_capture", release_capture); | 928 "release_capture", release_capture); |
| 1067 | 929 |
| 1068 attach_index_ = -1; | 930 attach_index_ = -1; |
| 1069 | 931 |
| 1070 // When the user detaches we assume they want to reorder. | 932 // When the user detaches we assume they want to reorder. |
| 1071 move_behavior_ = REORDER; | 933 move_behavior_ = REORDER; |
| 1072 | 934 |
| 1073 // Release ownership of the drag controller and mouse capture. When we | 935 // Release ownership of the drag controller and mouse capture. When we |
| 1074 // reattach ownership is transfered. | 936 // reattach ownership is transfered. |
| 1075 if (detach_into_browser_) { | 937 attached_tabstrip_->ReleaseDragController(); |
| 1076 attached_tabstrip_->ReleaseDragController(); | 938 if (release_capture == RELEASE_CAPTURE) |
| 1077 if (release_capture == RELEASE_CAPTURE) | 939 attached_tabstrip_->GetWidget()->ReleaseCapture(); |
| 1078 attached_tabstrip_->GetWidget()->ReleaseCapture(); | |
| 1079 } | |
| 1080 | 940 |
| 1081 mouse_move_direction_ = kMovedMouseLeft | kMovedMouseRight; | 941 mouse_move_direction_ = kMovedMouseLeft | kMovedMouseRight; |
| 1082 | 942 |
| 1083 // Prevent the WebContents HWND from being hidden by any of the model | |
| 1084 // operations performed during the drag. | |
| 1085 if (!detach_into_browser_) | |
| 1086 source_dragged_contents()->IncrementCapturerCount(gfx::Size()); | |
| 1087 | |
| 1088 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs(); | 943 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs(); |
| 1089 TabStripModel* attached_model = GetModel(attached_tabstrip_); | 944 TabStripModel* attached_model = GetModel(attached_tabstrip_); |
| 1090 std::vector<TabRendererData> tab_data; | 945 std::vector<TabRendererData> tab_data; |
| 1091 for (size_t i = 0; i < drag_data_.size(); ++i) { | 946 for (size_t i = 0; i < drag_data_.size(); ++i) { |
| 1092 tab_data.push_back(drag_data_[i].attached_tab->data()); | 947 tab_data.push_back(drag_data_[i].attached_tab->data()); |
| 1093 int index = attached_model->GetIndexOfWebContents(drag_data_[i].contents); | 948 int index = attached_model->GetIndexOfWebContents(drag_data_[i].contents); |
| 1094 DCHECK_NE(-1, index); | 949 DCHECK_NE(-1, index); |
| 1095 | 950 |
| 1096 // Hide the tab so that the user doesn't see it animate closed. | 951 // Hide the tab so that the user doesn't see it animate closed. |
| 1097 drag_data_[i].attached_tab->SetVisible(false); | 952 drag_data_[i].attached_tab->SetVisible(false); |
| 1098 drag_data_[i].attached_tab->set_detached(); | 953 drag_data_[i].attached_tab->set_detached(); |
| 1099 | 954 |
| 1100 attached_model->DetachWebContentsAt(index); | 955 attached_model->DetachWebContentsAt(index); |
| 1101 | 956 |
| 1102 // Detaching resets the delegate, but we still want to be the delegate. | |
| 1103 if (!detach_into_browser_) | |
| 1104 drag_data_[i].contents->SetDelegate(this); | |
| 1105 | |
| 1106 // Detaching may end up deleting the tab, drop references to it. | 957 // Detaching may end up deleting the tab, drop references to it. |
| 1107 drag_data_[i].attached_tab = NULL; | 958 drag_data_[i].attached_tab = NULL; |
| 1108 } | 959 } |
| 1109 | 960 |
| 1110 // If we've removed the last Tab from the TabStrip, hide the frame now. | 961 // If we've removed the last Tab from the TabStrip, hide the frame now. |
| 1111 if (!attached_model->empty()) { | 962 if (!attached_model->empty()) { |
| 1112 if (!selection_model_before_attach_.empty() && | 963 if (!selection_model_before_attach_.empty() && |
| 1113 selection_model_before_attach_.active() >= 0 && | 964 selection_model_before_attach_.active() >= 0 && |
| 1114 selection_model_before_attach_.active() < attached_model->count()) { | 965 selection_model_before_attach_.active() < attached_model->count()) { |
| 1115 // Restore the selection. | 966 // Restore the selection. |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1480 if (type == CANCELED) | 1331 if (type == CANCELED) |
| 1481 RevertDrag(); | 1332 RevertDrag(); |
| 1482 else | 1333 else |
| 1483 CompleteDrag(); | 1334 CompleteDrag(); |
| 1484 } | 1335 } |
| 1485 } else if (drag_data_.size() > 1) { | 1336 } else if (drag_data_.size() > 1) { |
| 1486 initial_selection_model_.Clear(); | 1337 initial_selection_model_.Clear(); |
| 1487 RevertDrag(); | 1338 RevertDrag(); |
| 1488 } // else case the only tab we were dragging was deleted. Nothing to do. | 1339 } // else case the only tab we were dragging was deleted. Nothing to do. |
| 1489 | 1340 |
| 1490 if (!detach_into_browser_) | |
| 1491 ResetDelegates(); | |
| 1492 | |
| 1493 // Clear out drag data so we don't attempt to do anything with it. | 1341 // Clear out drag data so we don't attempt to do anything with it. |
| 1494 drag_data_.clear(); | 1342 drag_data_.clear(); |
| 1495 | 1343 |
| 1496 TabStrip* owning_tabstrip = (attached_tabstrip_ && detach_into_browser_) ? | 1344 TabStrip* owning_tabstrip = attached_tabstrip_ ? |
| 1497 attached_tabstrip_ : source_tabstrip_; | 1345 attached_tabstrip_ : source_tabstrip_; |
| 1498 owning_tabstrip->DestroyDragController(); | 1346 owning_tabstrip->DestroyDragController(); |
| 1499 } | 1347 } |
| 1500 | 1348 |
| 1501 void TabDragController::RevertDrag() { | 1349 void TabDragController::RevertDrag() { |
| 1502 std::vector<Tab*> tabs; | 1350 std::vector<Tab*> tabs; |
| 1503 for (size_t i = 0; i < drag_data_.size(); ++i) { | 1351 for (size_t i = 0; i < drag_data_.size(); ++i) { |
| 1504 if (drag_data_[i].contents) { | 1352 if (drag_data_[i].contents) { |
| 1505 // Contents is NULL if a tab was destroyed while the drag was under way. | 1353 // Contents is NULL if a tab was destroyed while the drag was under way. |
| 1506 tabs.push_back(drag_data_[i].attached_tab); | 1354 tabs.push_back(drag_data_[i].attached_tab); |
| 1507 RevertDragAt(i); | 1355 RevertDragAt(i); |
| 1508 } | 1356 } |
| 1509 } | 1357 } |
| 1510 | 1358 |
| 1511 bool restore_frame = !detach_into_browser_ && | |
| 1512 attached_tabstrip_ != source_tabstrip_; | |
| 1513 if (attached_tabstrip_) { | 1359 if (attached_tabstrip_) { |
| 1514 if (did_restore_window_) | 1360 if (did_restore_window_) |
| 1515 MaximizeAttachedWindow(); | 1361 MaximizeAttachedWindow(); |
| 1516 if (attached_tabstrip_ == source_tabstrip_) { | 1362 if (attached_tabstrip_ == source_tabstrip_) { |
| 1517 source_tabstrip_->StoppedDraggingTabs( | 1363 source_tabstrip_->StoppedDraggingTabs( |
| 1518 tabs, initial_tab_positions_, move_behavior_ == MOVE_VISIBILE_TABS, | 1364 tabs, initial_tab_positions_, move_behavior_ == MOVE_VISIBILE_TABS, |
| 1519 false); | 1365 false); |
| 1520 } else { | 1366 } else { |
| 1521 attached_tabstrip_->DraggedTabsDetached(); | 1367 attached_tabstrip_->DraggedTabsDetached(); |
| 1522 } | 1368 } |
| 1523 } | 1369 } |
| 1524 | 1370 |
| 1525 if (initial_selection_model_.empty()) | 1371 if (initial_selection_model_.empty()) |
| 1526 ResetSelection(GetModel(source_tabstrip_)); | 1372 ResetSelection(GetModel(source_tabstrip_)); |
| 1527 else | 1373 else |
| 1528 GetModel(source_tabstrip_)->SetSelectionFromModel(initial_selection_model_); | 1374 GetModel(source_tabstrip_)->SetSelectionFromModel(initial_selection_model_); |
| 1529 | 1375 |
| 1530 // If we're not attached to any TabStrip, or attached to some other TabStrip, | 1376 if (source_tabstrip_) |
| 1531 // we need to restore the bounds of the original TabStrip's frame, in case | |
| 1532 // it has been hidden. | |
| 1533 if (restore_frame && !restore_bounds_.IsEmpty()) | |
| 1534 source_tabstrip_->GetWidget()->SetBounds(restore_bounds_); | |
| 1535 | |
| 1536 if (detach_into_browser_ && source_tabstrip_) | |
| 1537 source_tabstrip_->GetWidget()->Activate(); | 1377 source_tabstrip_->GetWidget()->Activate(); |
| 1538 | |
| 1539 // Return the WebContents to normalcy. If the tab was attached to a | |
| 1540 // TabStrip before the revert, the decrement has already occurred. | |
| 1541 // If the tab was destroyed, don't attempt to dereference the | |
| 1542 // WebContents pointer. | |
| 1543 if (!detach_into_browser_ && !attached_tabstrip_ && source_dragged_contents()) | |
| 1544 source_dragged_contents()->DecrementCapturerCount(); | |
| 1545 } | 1378 } |
| 1546 | 1379 |
| 1547 void TabDragController::ResetSelection(TabStripModel* model) { | 1380 void TabDragController::ResetSelection(TabStripModel* model) { |
| 1548 DCHECK(model); | 1381 DCHECK(model); |
| 1549 ui::ListSelectionModel selection_model; | 1382 ui::ListSelectionModel selection_model; |
| 1550 bool has_one_valid_tab = false; | 1383 bool has_one_valid_tab = false; |
| 1551 for (size_t i = 0; i < drag_data_.size(); ++i) { | 1384 for (size_t i = 0; i < drag_data_.size(); ++i) { |
| 1552 // |contents| is NULL if a tab was deleted out from under us. | 1385 // |contents| is NULL if a tab was deleted out from under us. |
| 1553 if (drag_data_[i].contents) { | 1386 if (drag_data_[i].contents) { |
| 1554 int index = model->GetIndexOfWebContents(drag_data_[i].contents); | 1387 int index = model->GetIndexOfWebContents(drag_data_[i].contents); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1663 item.add_types = drag_data_[i].pinned ? TabStripModel::ADD_PINNED | 1496 item.add_types = drag_data_[i].pinned ? TabStripModel::ADD_PINNED |
| 1664 : TabStripModel::ADD_NONE; | 1497 : TabStripModel::ADD_NONE; |
| 1665 contentses.push_back(item); | 1498 contentses.push_back(item); |
| 1666 } | 1499 } |
| 1667 | 1500 |
| 1668 Browser* new_browser = | 1501 Browser* new_browser = |
| 1669 GetModel(source_tabstrip_)->delegate()->CreateNewStripWithContents( | 1502 GetModel(source_tabstrip_)->delegate()->CreateNewStripWithContents( |
| 1670 contentses, window_bounds, widget->IsMaximized()); | 1503 contentses, window_bounds, widget->IsMaximized()); |
| 1671 ResetSelection(new_browser->tab_strip_model()); | 1504 ResetSelection(new_browser->tab_strip_model()); |
| 1672 new_browser->window()->Show(); | 1505 new_browser->window()->Show(); |
| 1673 | |
| 1674 // Return the WebContents to normalcy. | |
| 1675 if (!detach_into_browser_) | |
| 1676 source_dragged_contents()->DecrementCapturerCount(); | |
| 1677 } | 1506 } |
| 1678 | |
| 1679 CleanUpHiddenFrame(); | |
| 1680 } | 1507 } |
| 1681 | 1508 |
| 1682 void TabDragController::MaximizeAttachedWindow() { | 1509 void TabDragController::MaximizeAttachedWindow() { |
| 1683 GetAttachedBrowserWidget()->Maximize(); | 1510 GetAttachedBrowserWidget()->Maximize(); |
| 1684 if (was_source_fullscreen_ && | 1511 if (was_source_fullscreen_ && |
| 1685 host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH) { | 1512 host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH) { |
| 1686 // In fullscreen mode it is only possible to get here if the source | 1513 // In fullscreen mode it is only possible to get here if the source |
| 1687 // was in "immersive fullscreen" mode, so toggle it back on. | 1514 // was in "immersive fullscreen" mode, so toggle it back on. |
| 1688 ash::accelerators::ToggleFullscreen(); | 1515 ash::accelerators::ToggleFullscreen(); |
| 1689 } | 1516 } |
| 1690 } | 1517 } |
| 1691 | 1518 |
| 1692 void TabDragController::ResetDelegates() { | |
| 1693 DCHECK(!detach_into_browser_); | |
| 1694 for (size_t i = 0; i < drag_data_.size(); ++i) { | |
| 1695 if (drag_data_[i].contents && | |
| 1696 drag_data_[i].contents->GetDelegate() == this) { | |
| 1697 drag_data_[i].contents->SetDelegate( | |
| 1698 drag_data_[i].original_delegate); | |
| 1699 } | |
| 1700 } | |
| 1701 } | |
| 1702 | |
| 1703 gfx::Rect TabDragController::GetViewScreenBounds( | 1519 gfx::Rect TabDragController::GetViewScreenBounds( |
| 1704 views::View* view) const { | 1520 views::View* view) const { |
| 1705 gfx::Point view_topleft; | 1521 gfx::Point view_topleft; |
| 1706 views::View::ConvertPointToScreen(view, &view_topleft); | 1522 views::View::ConvertPointToScreen(view, &view_topleft); |
| 1707 gfx::Rect view_screen_bounds = view->GetLocalBounds(); | 1523 gfx::Rect view_screen_bounds = view->GetLocalBounds(); |
| 1708 view_screen_bounds.Offset(view_topleft.x(), view_topleft.y()); | 1524 view_screen_bounds.Offset(view_topleft.x(), view_topleft.y()); |
| 1709 return view_screen_bounds; | 1525 return view_screen_bounds; |
| 1710 } | 1526 } |
| 1711 | 1527 |
| 1712 void TabDragController::CleanUpHiddenFrame() { | |
| 1713 // If the model we started dragging from is now empty, we must ask the | |
| 1714 // delegate to close the frame. | |
| 1715 if (!detach_into_browser_ && GetModel(source_tabstrip_)->empty()) | |
| 1716 GetModel(source_tabstrip_)->delegate()->CloseFrameAfterDragSession(); | |
| 1717 } | |
| 1718 | |
| 1719 void TabDragController::BringWindowUnderPointToFront( | 1528 void TabDragController::BringWindowUnderPointToFront( |
| 1720 const gfx::Point& point_in_screen) { | 1529 const gfx::Point& point_in_screen) { |
| 1721 aura::Window* window = GetLocalProcessWindow(point_in_screen, true); | 1530 aura::Window* window = GetLocalProcessWindow(point_in_screen, true); |
| 1722 | 1531 |
| 1723 // Only bring browser windows to front - only windows with a TabStrip can | 1532 // Only bring browser windows to front - only windows with a TabStrip can |
| 1724 // be tab drag targets. | 1533 // be tab drag targets. |
| 1725 if (!GetTabStripForWindow(window)) | 1534 if (!GetTabStripForWindow(window)) |
| 1726 return; | 1535 return; |
| 1727 | 1536 |
| 1728 if (window) { | 1537 if (window) { |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1913 DCHECK(got_touch_point); | 1722 DCHECK(got_touch_point); |
| 1914 ash::wm::ConvertPointToScreen(widget_window->GetRootWindow(), &touch_point); | 1723 ash::wm::ConvertPointToScreen(widget_window->GetRootWindow(), &touch_point); |
| 1915 return touch_point; | 1724 return touch_point; |
| 1916 } | 1725 } |
| 1917 | 1726 |
| 1918 return screen_->GetCursorScreenPoint(); | 1727 return screen_->GetCursorScreenPoint(); |
| 1919 } | 1728 } |
| 1920 | 1729 |
| 1921 gfx::Vector2d TabDragController::GetWindowOffset( | 1730 gfx::Vector2d TabDragController::GetWindowOffset( |
| 1922 const gfx::Point& point_in_screen) { | 1731 const gfx::Point& point_in_screen) { |
| 1923 TabStrip* owning_tabstrip = (attached_tabstrip_ && detach_into_browser_) ? | 1732 TabStrip* owning_tabstrip = attached_tabstrip_ ? |
| 1924 attached_tabstrip_ : source_tabstrip_; | 1733 attached_tabstrip_ : source_tabstrip_; |
| 1925 views::View* toplevel_view = owning_tabstrip->GetWidget()->GetContentsView(); | 1734 views::View* toplevel_view = owning_tabstrip->GetWidget()->GetContentsView(); |
| 1926 | 1735 |
| 1927 gfx::Point point = point_in_screen; | 1736 gfx::Point point = point_in_screen; |
| 1928 views::View::ConvertPointFromScreen(toplevel_view, &point); | 1737 views::View::ConvertPointFromScreen(toplevel_view, &point); |
| 1929 return point.OffsetFromOrigin(); | 1738 return point.OffsetFromOrigin(); |
| 1930 } | 1739 } |
| 1931 | 1740 |
| 1932 gfx::NativeWindow TabDragController::GetLocalProcessWindow( | 1741 gfx::NativeWindow TabDragController::GetLocalProcessWindow( |
| 1933 const gfx::Point& screen_point, | 1742 const gfx::Point& screen_point, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1951 it != browser_list->end(); ++it) { | 1760 it != browser_list->end(); ++it) { |
| 1952 if ((*it)->tab_strip_model()->empty()) | 1761 if ((*it)->tab_strip_model()->empty()) |
| 1953 exclude.insert((*it)->window()->GetNativeWindow()); | 1762 exclude.insert((*it)->window()->GetNativeWindow()); |
| 1954 } | 1763 } |
| 1955 #endif | 1764 #endif |
| 1956 return GetLocalProcessWindowAtPoint(host_desktop_type_, | 1765 return GetLocalProcessWindowAtPoint(host_desktop_type_, |
| 1957 screen_point, | 1766 screen_point, |
| 1958 exclude); | 1767 exclude); |
| 1959 | 1768 |
| 1960 } | 1769 } |
| OLD | NEW |