Chromium Code Reviews| 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" |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 160 | 160 |
| 161 // static | 161 // static |
| 162 const int TabDragController::kVerticalDetachMagnetism = 15; | 162 const int TabDragController::kVerticalDetachMagnetism = 15; |
| 163 | 163 |
| 164 TabDragController::TabDragController() | 164 TabDragController::TabDragController() |
| 165 : event_source_(EVENT_SOURCE_MOUSE), | 165 : event_source_(EVENT_SOURCE_MOUSE), |
| 166 source_tabstrip_(NULL), | 166 source_tabstrip_(NULL), |
| 167 attached_tabstrip_(NULL), | 167 attached_tabstrip_(NULL), |
| 168 screen_(NULL), | 168 screen_(NULL), |
| 169 host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE), | 169 host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE), |
| 170 use_aura_capture_policy_(false), | 170 can_release_capture_(true), |
| 171 offset_to_width_ratio_(0), | 171 offset_to_width_ratio_(0), |
| 172 old_focused_view_id_( | 172 old_focused_view_id_( |
| 173 views::ViewStorage::GetInstance()->CreateStorageID()), | 173 views::ViewStorage::GetInstance()->CreateStorageID()), |
| 174 last_move_screen_loc_(0), | 174 last_move_screen_loc_(0), |
| 175 started_drag_(false), | 175 started_drag_(false), |
| 176 active_(true), | 176 active_(true), |
| 177 source_tab_index_(std::numeric_limits<size_t>::max()), | 177 source_tab_index_(std::numeric_limits<size_t>::max()), |
| 178 initial_move_(true), | 178 initial_move_(true), |
| 179 move_behavior_(REORDER), | 179 move_behavior_(REORDER), |
| 180 mouse_move_direction_(0), | 180 mouse_move_direction_(0), |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 DCHECK(!tabs.empty()); | 227 DCHECK(!tabs.empty()); |
| 228 DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end()); | 228 DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end()); |
| 229 source_tabstrip_ = source_tabstrip; | 229 source_tabstrip_ = source_tabstrip; |
| 230 was_source_maximized_ = source_tabstrip->GetWidget()->IsMaximized(); | 230 was_source_maximized_ = source_tabstrip->GetWidget()->IsMaximized(); |
| 231 was_source_fullscreen_ = source_tabstrip->GetWidget()->IsFullscreen(); | 231 was_source_fullscreen_ = source_tabstrip->GetWidget()->IsFullscreen(); |
| 232 screen_ = gfx::Screen::GetScreenFor( | 232 screen_ = gfx::Screen::GetScreenFor( |
| 233 source_tabstrip->GetWidget()->GetNativeView()); | 233 source_tabstrip->GetWidget()->GetNativeView()); |
| 234 host_desktop_type_ = chrome::GetHostDesktopTypeForNativeView( | 234 host_desktop_type_ = chrome::GetHostDesktopTypeForNativeView( |
| 235 source_tabstrip->GetWidget()->GetNativeView()); | 235 source_tabstrip->GetWidget()->GetNativeView()); |
| 236 #if defined(OS_LINUX) | 236 #if defined(OS_LINUX) |
| 237 use_aura_capture_policy_ = true; | 237 // Mouse capture is not synchronous on desktop Linux. Chrome makes |
| 238 // transferring capture between widgets without releasing capture appear | |
| 239 // synchronous on desktop Linux, so use that. | |
| 240 can_release_capture_ = false; | |
|
sky
2014/08/13 19:14:53
What about when running ash on linux (not chromeos
pkotwicz
2014/08/15 20:30:49
I moved the comments outside of the ifdefs. Should
| |
| 238 #else | 241 #else |
| 239 use_aura_capture_policy_ = | 242 // Do not release capture when transferring capture on Ash because releasing |
| 240 (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH); | 243 // capture cancels gestures. |
| 244 can_release_capture_ = | |
| 245 (host_desktop_type_ != chrome::HOST_DESKTOP_TYPE_ASH); | |
| 241 #endif | 246 #endif |
| 242 start_point_in_screen_ = gfx::Point(source_tab_offset, mouse_offset.y()); | 247 start_point_in_screen_ = gfx::Point(source_tab_offset, mouse_offset.y()); |
| 243 views::View::ConvertPointToScreen(source_tab, &start_point_in_screen_); | 248 views::View::ConvertPointToScreen(source_tab, &start_point_in_screen_); |
| 244 event_source_ = event_source; | 249 event_source_ = event_source; |
| 245 mouse_offset_ = mouse_offset; | 250 mouse_offset_ = mouse_offset; |
| 246 move_behavior_ = move_behavior; | 251 move_behavior_ = move_behavior; |
| 247 last_point_in_screen_ = start_point_in_screen_; | 252 last_point_in_screen_ = start_point_in_screen_; |
| 248 last_move_screen_loc_ = start_point_in_screen_.x(); | 253 last_move_screen_loc_ = start_point_in_screen_.x(); |
| 249 initial_tab_positions_ = source_tabstrip->GetTabXCoordinates(); | 254 initial_tab_positions_ = source_tabstrip->GetTabXCoordinates(); |
| 250 | 255 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 541 "point_in_screen", point_in_screen.ToString()); | 546 "point_in_screen", point_in_screen.ToString()); |
| 542 | 547 |
| 543 if (!target_tabstrip) { | 548 if (!target_tabstrip) { |
| 544 DetachIntoNewBrowserAndRunMoveLoop(point_in_screen); | 549 DetachIntoNewBrowserAndRunMoveLoop(point_in_screen); |
| 545 return DRAG_BROWSER_RESULT_STOP; | 550 return DRAG_BROWSER_RESULT_STOP; |
| 546 } | 551 } |
| 547 if (is_dragging_window_) { | 552 if (is_dragging_window_) { |
| 548 // ReleaseCapture() is going to result in calling back to us (because it | 553 // ReleaseCapture() is going to result in calling back to us (because it |
| 549 // results in a move). That'll cause all sorts of problems. Reset the | 554 // results in a move). That'll cause all sorts of problems. Reset the |
| 550 // observer so we don't get notified and process the event. | 555 // observer so we don't get notified and process the event. |
| 551 if (use_aura_capture_policy_) { | 556 if (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH) { |
|
sky
2014/08/13 19:14:53
Why isn't this can_release_capture_?
pkotwicz
2014/08/15 20:30:49
The behavior described in the comment applies to a
| |
| 552 move_loop_widget_->RemoveObserver(this); | 557 move_loop_widget_->RemoveObserver(this); |
| 553 move_loop_widget_ = NULL; | 558 move_loop_widget_ = NULL; |
| 554 } | 559 } |
| 555 views::Widget* browser_widget = GetAttachedBrowserWidget(); | 560 views::Widget* browser_widget = GetAttachedBrowserWidget(); |
| 556 // Need to release the drag controller before starting the move loop as it's | 561 // Need to release the drag controller before starting the move loop as it's |
| 557 // going to trigger capture lost, which cancels drag. | 562 // going to trigger capture lost, which cancels drag. |
| 558 attached_tabstrip_->ReleaseDragController(); | 563 attached_tabstrip_->ReleaseDragController(); |
| 559 target_tabstrip->OwnDragController(this); | 564 target_tabstrip->OwnDragController(this); |
| 560 // Disable animations so that we don't see a close animation on aero. | 565 // Disable animations so that we don't see a close animation on aero. |
| 561 browser_widget->SetVisibilityChangedAnimationsEnabled(false); | 566 browser_widget->SetVisibilityChangedAnimationsEnabled(false); |
| 562 // For aura we can't release capture, otherwise it'll cancel a gesture. | 567 if (can_release_capture_) |
| 563 // Instead we have to directly change capture. | 568 browser_widget->ReleaseCapture(); |
| 564 if (use_aura_capture_policy_) | 569 else |
| 565 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_); | 570 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_); |
| 566 else | |
| 567 browser_widget->ReleaseCapture(); | |
| 568 #if defined(OS_WIN) | 571 #if defined(OS_WIN) |
| 569 // The Gesture recognizer does not work well currently when capture changes | 572 // The Gesture recognizer does not work well currently when capture changes |
| 570 // while a touch gesture is in progress. So we need to manually transfer | 573 // while a touch gesture is in progress. So we need to manually transfer |
| 571 // gesture sequence and the GR's touch events queue to the new window. This | 574 // gesture sequence and the GR's touch events queue to the new window. This |
| 572 // should really be done somewhere in capture change code and or inside the | 575 // should really be done somewhere in capture change code and or inside the |
| 573 // GR. But we currently do not have a consistent way for doing it that would | 576 // GR. But we currently do not have a consistent way for doing it that would |
| 574 // work in all cases. Hence this hack. | 577 // work in all cases. Hence this hack. |
| 575 ui::GestureRecognizer::Get()->TransferEventsTo( | 578 ui::GestureRecognizer::Get()->TransferEventsTo( |
| 576 browser_widget->GetNativeView(), | 579 browser_widget->GetNativeView(), |
| 577 target_tabstrip->GetWidget()->GetNativeView()); | 580 target_tabstrip->GetWidget()->GetNativeView()); |
| 578 #endif | 581 #endif |
| 579 | 582 |
| 580 // The window is going away. Since the drag is still on going we don't want | 583 // The window is going away. Since the drag is still on going we don't want |
| 581 // that to effect the position of any windows. | 584 // that to effect the position of any windows. |
| 582 SetWindowPositionManaged(browser_widget->GetNativeView(), false); | 585 SetWindowPositionManaged(browser_widget->GetNativeView(), false); |
| 583 | 586 |
| 584 #if !defined(OS_LINUX) || defined(OS_CHROMEOS) | 587 #if !defined(OS_LINUX) || defined(OS_CHROMEOS) |
| 585 // EndMoveLoop is going to snap the window back to its original location. | 588 // EndMoveLoop is going to snap the window back to its original location. |
| 586 // Hide it so users don't see this. Hiding a window in Linux aura causes | 589 // Hide it so users don't see this. Hiding a window in Linux aura causes |
| 587 // it to lose capture so skip it. | 590 // it to lose capture so skip it. |
| 588 browser_widget->Hide(); | 591 browser_widget->Hide(); |
| 589 #endif | 592 #endif |
| 590 browser_widget->EndMoveLoop(); | 593 browser_widget->EndMoveLoop(); |
| 591 | 594 |
| 592 // Ideally we would always swap the tabs now, but on non-ash it seems that | 595 // Ideally we would always swap the tabs now, but on non-ash Windows, it |
|
sky
2014/08/13 19:14:53
This is confusing now as it doesn't mention can_re
pkotwicz
2014/08/15 20:30:49
I changed the comment to make it more accurate. I
| |
| 593 // running the move loop implicitly activates the window when done, leading | 596 // seems that running the move loop implicitly activates the window when |
| 594 // to all sorts of flicker. So, on non-ash, instead we process the move | 597 // done, leading to all sorts of flicker. So, on non-ash Windows, instead |
| 595 // after the loop completes. But on chromeos, we can do tab swapping now to | 598 // we process the move after the loop completes. But on chromeos, we can |
| 596 // avoid the tab flashing issue(crbug.com/116329). | 599 // do tab swapping now to avoid the tab flashing issue |
| 597 if (use_aura_capture_policy_) { | 600 // (crbug.com/116329). |
| 601 if (can_release_capture_) { | |
| 602 tab_strip_to_attach_to_after_exit_ = target_tabstrip; | |
| 603 } else { | |
| 598 is_dragging_window_ = false; | 604 is_dragging_window_ = false; |
| 599 Detach(DONT_RELEASE_CAPTURE); | 605 Detach(DONT_RELEASE_CAPTURE); |
| 600 Attach(target_tabstrip, point_in_screen); | 606 Attach(target_tabstrip, point_in_screen); |
| 601 // Move the tabs into position. | 607 // Move the tabs into position. |
| 602 MoveAttached(point_in_screen); | 608 MoveAttached(point_in_screen); |
| 603 attached_tabstrip_->GetWidget()->Activate(); | 609 attached_tabstrip_->GetWidget()->Activate(); |
| 604 } else { | |
| 605 tab_strip_to_attach_to_after_exit_ = target_tabstrip; | |
| 606 } | 610 } |
| 607 | 611 |
| 608 waiting_for_run_loop_to_exit_ = true; | 612 waiting_for_run_loop_to_exit_ = true; |
| 609 end_run_loop_behavior_ = END_RUN_LOOP_CONTINUE_DRAGGING; | 613 end_run_loop_behavior_ = END_RUN_LOOP_CONTINUE_DRAGGING; |
| 610 return DRAG_BROWSER_RESULT_STOP; | 614 return DRAG_BROWSER_RESULT_STOP; |
| 611 } | 615 } |
| 612 Detach(DONT_RELEASE_CAPTURE); | 616 Detach(DONT_RELEASE_CAPTURE); |
| 613 Attach(target_tabstrip, point_in_screen); | 617 Attach(target_tabstrip, point_in_screen); |
| 614 return DRAG_BROWSER_RESULT_CONTINUE; | 618 return DRAG_BROWSER_RESULT_CONTINUE; |
| 615 } | 619 } |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 984 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs(); | 988 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs(); |
| 985 OffsetX(GetAttachedDragPoint(point_in_screen).x(), &drag_bounds); | 989 OffsetX(GetAttachedDragPoint(point_in_screen).x(), &drag_bounds); |
| 986 | 990 |
| 987 gfx::Vector2d drag_offset; | 991 gfx::Vector2d drag_offset; |
| 988 Browser* browser = CreateBrowserForDrag( | 992 Browser* browser = CreateBrowserForDrag( |
| 989 attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds); | 993 attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds); |
| 990 #if defined(OS_WIN) | 994 #if defined(OS_WIN) |
| 991 gfx::NativeView attached_native_view = | 995 gfx::NativeView attached_native_view = |
| 992 attached_tabstrip_->GetWidget()->GetNativeView(); | 996 attached_tabstrip_->GetWidget()->GetNativeView(); |
| 993 #endif | 997 #endif |
| 994 Detach(use_aura_capture_policy_ ? DONT_RELEASE_CAPTURE : RELEASE_CAPTURE); | 998 Detach(can_release_capture_ ? RELEASE_CAPTURE : DONT_RELEASE_CAPTURE); |
| 995 BrowserView* dragged_browser_view = | 999 BrowserView* dragged_browser_view = |
| 996 BrowserView::GetBrowserViewForBrowser(browser); | 1000 BrowserView::GetBrowserViewForBrowser(browser); |
| 997 views::Widget* dragged_widget = dragged_browser_view->GetWidget(); | 1001 views::Widget* dragged_widget = dragged_browser_view->GetWidget(); |
| 998 #if defined(OS_WIN) | 1002 #if defined(OS_WIN) |
| 999 // The Gesture recognizer does not work well currently when capture changes | 1003 // The Gesture recognizer does not work well currently when capture changes |
| 1000 // while a touch gesture is in progress. So we need to manually transfer | 1004 // while a touch gesture is in progress. So we need to manually transfer |
| 1001 // gesture sequence and the GR's touch events queue to the new window. This | 1005 // gesture sequence and the GR's touch events queue to the new window. This |
| 1002 // should really be done somewhere in capture change code and or inside the | 1006 // should really be done somewhere in capture change code and or inside the |
| 1003 // GR. But we currently do not have a consistent way for doing it that would | 1007 // GR. But we currently do not have a consistent way for doing it that would |
| 1004 // work in all cases. Hence this hack. | 1008 // work in all cases. Hence this hack. |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1029 void TabDragController::RunMoveLoop(const gfx::Vector2d& drag_offset) { | 1033 void TabDragController::RunMoveLoop(const gfx::Vector2d& drag_offset) { |
| 1030 // If the user drags the whole window we'll assume they are going to attach to | 1034 // If the user drags the whole window we'll assume they are going to attach to |
| 1031 // another window and therefore want to reorder. | 1035 // another window and therefore want to reorder. |
| 1032 move_behavior_ = REORDER; | 1036 move_behavior_ = REORDER; |
| 1033 | 1037 |
| 1034 move_loop_widget_ = GetAttachedBrowserWidget(); | 1038 move_loop_widget_ = GetAttachedBrowserWidget(); |
| 1035 DCHECK(move_loop_widget_); | 1039 DCHECK(move_loop_widget_); |
| 1036 move_loop_widget_->AddObserver(this); | 1040 move_loop_widget_->AddObserver(this); |
| 1037 is_dragging_window_ = true; | 1041 is_dragging_window_ = true; |
| 1038 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); | 1042 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); |
| 1039 // Running the move loop releases mouse capture on non-ash, which triggers | 1043 if (can_release_capture_) { |
| 1040 // destroying the drag loop. Release mouse capture ourself before this while | 1044 // Running the move loop releases mouse capture, which triggers destroying |
| 1041 // the DragController isn't owned by the TabStrip. | 1045 // the drag loop. Release mouse capture now while the DragController is not |
| 1042 if (host_desktop_type_ != chrome::HOST_DESKTOP_TYPE_ASH) { | 1046 // owned by the TabStrip. |
| 1043 attached_tabstrip_->ReleaseDragController(); | 1047 attached_tabstrip_->ReleaseDragController(); |
| 1044 attached_tabstrip_->GetWidget()->ReleaseCapture(); | 1048 attached_tabstrip_->GetWidget()->ReleaseCapture(); |
| 1045 attached_tabstrip_->OwnDragController(this); | 1049 attached_tabstrip_->OwnDragController(this); |
| 1046 } | 1050 } |
| 1047 const views::Widget::MoveLoopSource move_loop_source = | 1051 const views::Widget::MoveLoopSource move_loop_source = |
| 1048 event_source_ == EVENT_SOURCE_MOUSE ? | 1052 event_source_ == EVENT_SOURCE_MOUSE ? |
| 1049 views::Widget::MOVE_LOOP_SOURCE_MOUSE : | 1053 views::Widget::MOVE_LOOP_SOURCE_MOUSE : |
| 1050 views::Widget::MOVE_LOOP_SOURCE_TOUCH; | 1054 views::Widget::MOVE_LOOP_SOURCE_TOUCH; |
| 1051 const views::Widget::MoveLoopEscapeBehavior escape_behavior = | 1055 const views::Widget::MoveLoopEscapeBehavior escape_behavior = |
| 1052 is_dragging_new_browser_ ? | 1056 is_dragging_new_browser_ ? |
| 1053 views::Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_HIDE : | 1057 views::Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_HIDE : |
| 1054 views::Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_DONT_HIDE; | 1058 views::Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_DONT_HIDE; |
| 1055 views::Widget::MoveLoopResult result = | 1059 views::Widget::MoveLoopResult result = |
| 1056 move_loop_widget_->RunMoveLoop( | 1060 move_loop_widget_->RunMoveLoop( |
| 1057 drag_offset, move_loop_source, escape_behavior); | 1061 drag_offset, move_loop_source, escape_behavior); |
| 1058 content::NotificationService::current()->Notify( | 1062 content::NotificationService::current()->Notify( |
| 1059 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, | 1063 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, |
| 1060 content::NotificationService::AllBrowserContextsAndSources(), | 1064 content::NotificationService::AllBrowserContextsAndSources(), |
| 1061 content::NotificationService::NoDetails()); | 1065 content::NotificationService::NoDetails()); |
| 1062 | 1066 |
| 1063 if (!ref) | 1067 if (!ref) |
| 1064 return; | 1068 return; |
| 1065 // Under chromeos we immediately set the |move_loop_widget_| to NULL. | |
| 1066 if (move_loop_widget_) { | 1069 if (move_loop_widget_) { |
| 1067 move_loop_widget_->RemoveObserver(this); | 1070 move_loop_widget_->RemoveObserver(this); |
| 1068 move_loop_widget_ = NULL; | 1071 move_loop_widget_ = NULL; |
| 1069 } | 1072 } |
| 1070 is_dragging_window_ = false; | 1073 is_dragging_window_ = false; |
| 1071 waiting_for_run_loop_to_exit_ = false; | 1074 waiting_for_run_loop_to_exit_ = false; |
| 1072 if (end_run_loop_behavior_ == END_RUN_LOOP_CONTINUE_DRAGGING) { | 1075 if (end_run_loop_behavior_ == END_RUN_LOOP_CONTINUE_DRAGGING) { |
| 1073 end_run_loop_behavior_ = END_RUN_LOOP_STOP_DRAGGING; | 1076 end_run_loop_behavior_ = END_RUN_LOOP_STOP_DRAGGING; |
| 1074 if (tab_strip_to_attach_to_after_exit_) { | 1077 if (tab_strip_to_attach_to_after_exit_) { |
| 1075 gfx::Point point_in_screen(GetCursorScreenPoint()); | 1078 gfx::Point point_in_screen(GetCursorScreenPoint()); |
| (...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1754 it != browser_list->end(); ++it) { | 1757 it != browser_list->end(); ++it) { |
| 1755 if ((*it)->tab_strip_model()->empty()) | 1758 if ((*it)->tab_strip_model()->empty()) |
| 1756 exclude.insert((*it)->window()->GetNativeWindow()); | 1759 exclude.insert((*it)->window()->GetNativeWindow()); |
| 1757 } | 1760 } |
| 1758 #endif | 1761 #endif |
| 1759 return GetLocalProcessWindowAtPoint(host_desktop_type_, | 1762 return GetLocalProcessWindowAtPoint(host_desktop_type_, |
| 1760 screen_point, | 1763 screen_point, |
| 1761 exclude); | 1764 exclude); |
| 1762 | 1765 |
| 1763 } | 1766 } |
| OLD | NEW |