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 |