Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(490)

Side by Side Diff: chrome/browser/ui/views/tabs/tab_drag_controller.cc

Issue 180983002: Avoids releasing capture prematurily when dragging tabs from one to another browser window (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Uses Aura mouse capture and release code path on Linux Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 // static 155 // static
156 const int TabDragController::kVerticalDetachMagnetism = 15; 156 const int TabDragController::kVerticalDetachMagnetism = 15;
157 157
158 TabDragController::TabDragController() 158 TabDragController::TabDragController()
159 : detach_into_browser_(true), 159 : detach_into_browser_(true),
160 event_source_(EVENT_SOURCE_MOUSE), 160 event_source_(EVENT_SOURCE_MOUSE),
161 source_tabstrip_(NULL), 161 source_tabstrip_(NULL),
162 attached_tabstrip_(NULL), 162 attached_tabstrip_(NULL),
163 screen_(NULL), 163 screen_(NULL),
164 host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE), 164 host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE),
165 use_aura_capture_policy_(false),
165 offset_to_width_ratio_(0), 166 offset_to_width_ratio_(0),
166 old_focused_view_id_( 167 old_focused_view_id_(
167 views::ViewStorage::GetInstance()->CreateStorageID()), 168 views::ViewStorage::GetInstance()->CreateStorageID()),
168 last_move_screen_loc_(0), 169 last_move_screen_loc_(0),
169 started_drag_(false), 170 started_drag_(false),
170 active_(true), 171 active_(true),
171 source_tab_index_(std::numeric_limits<size_t>::max()), 172 source_tab_index_(std::numeric_limits<size_t>::max()),
172 initial_move_(true), 173 initial_move_(true),
173 detach_behavior_(DETACHABLE), 174 detach_behavior_(DETACHABLE),
174 move_behavior_(REORDER), 175 move_behavior_(REORDER),
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 EventSource event_source) { 230 EventSource event_source) {
230 DCHECK(!tabs.empty()); 231 DCHECK(!tabs.empty());
231 DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end()); 232 DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end());
232 source_tabstrip_ = source_tabstrip; 233 source_tabstrip_ = source_tabstrip;
233 was_source_maximized_ = source_tabstrip->GetWidget()->IsMaximized(); 234 was_source_maximized_ = source_tabstrip->GetWidget()->IsMaximized();
234 was_source_fullscreen_ = source_tabstrip->GetWidget()->IsFullscreen(); 235 was_source_fullscreen_ = source_tabstrip->GetWidget()->IsFullscreen();
235 screen_ = gfx::Screen::GetScreenFor( 236 screen_ = gfx::Screen::GetScreenFor(
236 source_tabstrip->GetWidget()->GetNativeView()); 237 source_tabstrip->GetWidget()->GetNativeView());
237 host_desktop_type_ = chrome::GetHostDesktopTypeForNativeView( 238 host_desktop_type_ = chrome::GetHostDesktopTypeForNativeView(
238 source_tabstrip->GetWidget()->GetNativeView()); 239 source_tabstrip->GetWidget()->GetNativeView());
240 #if defined(OS_LINUX)
241 use_aura_capture_policy_ = true;
242 #else
243 use_aura_capture_policy_ =
244 (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH);
245 #endif
239 start_point_in_screen_ = gfx::Point(source_tab_offset, mouse_offset.y()); 246 start_point_in_screen_ = gfx::Point(source_tab_offset, mouse_offset.y());
240 views::View::ConvertPointToScreen(source_tab, &start_point_in_screen_); 247 views::View::ConvertPointToScreen(source_tab, &start_point_in_screen_);
241 event_source_ = event_source; 248 event_source_ = event_source;
242 mouse_offset_ = mouse_offset; 249 mouse_offset_ = mouse_offset;
243 detach_behavior_ = detach_behavior; 250 detach_behavior_ = detach_behavior;
244 move_behavior_ = move_behavior; 251 move_behavior_ = move_behavior;
245 last_point_in_screen_ = start_point_in_screen_; 252 last_point_in_screen_ = start_point_in_screen_;
246 last_move_screen_loc_ = start_point_in_screen_.x(); 253 last_move_screen_loc_ = start_point_in_screen_.x();
247 initial_tab_positions_ = source_tabstrip->GetTabXCoordinates(); 254 initial_tab_positions_ = source_tabstrip->GetTabXCoordinates();
248 if (detach_behavior == NOT_DETACHABLE) 255 if (detach_behavior == NOT_DETACHABLE)
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 "point_in_screen", point_in_screen.ToString()); 659 "point_in_screen", point_in_screen.ToString());
653 660
654 if (!target_tabstrip) { 661 if (!target_tabstrip) {
655 DetachIntoNewBrowserAndRunMoveLoop(point_in_screen); 662 DetachIntoNewBrowserAndRunMoveLoop(point_in_screen);
656 return DRAG_BROWSER_RESULT_STOP; 663 return DRAG_BROWSER_RESULT_STOP;
657 } 664 }
658 if (is_dragging_window_) { 665 if (is_dragging_window_) {
659 // ReleaseCapture() is going to result in calling back to us (because it 666 // ReleaseCapture() is going to result in calling back to us (because it
660 // results in a move). That'll cause all sorts of problems. Reset the 667 // results in a move). That'll cause all sorts of problems. Reset the
661 // observer so we don't get notified and process the event. 668 // observer so we don't get notified and process the event.
662 if (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH) { 669 if (use_aura_capture_policy_) {
663 move_loop_widget_->RemoveObserver(this); 670 move_loop_widget_->RemoveObserver(this);
664 move_loop_widget_ = NULL; 671 move_loop_widget_ = NULL;
665 } 672 }
666 views::Widget* browser_widget = GetAttachedBrowserWidget(); 673 views::Widget* browser_widget = GetAttachedBrowserWidget();
667 // Need to release the drag controller before starting the move loop as it's 674 // Need to release the drag controller before starting the move loop as it's
668 // going to trigger capture lost, which cancels drag. 675 // going to trigger capture lost, which cancels drag.
669 attached_tabstrip_->ReleaseDragController(); 676 attached_tabstrip_->ReleaseDragController();
670 target_tabstrip->OwnDragController(this); 677 target_tabstrip->OwnDragController(this);
671 // Disable animations so that we don't see a close animation on aero. 678 // Disable animations so that we don't see a close animation on aero.
672 browser_widget->SetVisibilityChangedAnimationsEnabled(false); 679 browser_widget->SetVisibilityChangedAnimationsEnabled(false);
673 // For aura we can't release capture, otherwise it'll cancel a gesture. 680 // For aura we can't release capture, otherwise it'll cancel a gesture.
674 // Instead we have to directly change capture. 681 // Instead we have to directly change capture.
675 if (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH) 682 if (use_aura_capture_policy_)
676 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_); 683 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_);
677 else 684 else
678 browser_widget->ReleaseCapture(); 685 browser_widget->ReleaseCapture();
679 #if defined(OS_WIN) 686 #if defined(OS_WIN)
680 // The Gesture recognizer does not work well currently when capture changes 687 // The Gesture recognizer does not work well currently when capture changes
681 // while a touch gesture is in progress. So we need to manually transfer 688 // while a touch gesture is in progress. So we need to manually transfer
682 // gesture sequence and the GR's touch events queue to the new window. This 689 // gesture sequence and the GR's touch events queue to the new window. This
683 // should really be done somewhere in capture change code and or inside the 690 // should really be done somewhere in capture change code and or inside the
684 // GR. But we currently do not have a consistent way for doing it that would 691 // GR. But we currently do not have a consistent way for doing it that would
685 // work in all cases. Hence this hack. 692 // work in all cases. Hence this hack.
686 ui::GestureRecognizer::Get()->TransferEventsTo( 693 ui::GestureRecognizer::Get()->TransferEventsTo(
687 browser_widget->GetNativeView(), 694 browser_widget->GetNativeView(),
688 target_tabstrip->GetWidget()->GetNativeView()); 695 target_tabstrip->GetWidget()->GetNativeView());
689 #endif 696 #endif
690 697
691 // The window is going away. Since the drag is still on going we don't want 698 // The window is going away. Since the drag is still on going we don't want
692 // that to effect the position of any windows. 699 // that to effect the position of any windows.
693 SetWindowPositionManaged(browser_widget->GetNativeView(), false); 700 SetWindowPositionManaged(browser_widget->GetNativeView(), false);
694 701
702 #if !defined(OS_LINUX) || defined(OS_CHROMEOS)
695 // EndMoveLoop is going to snap the window back to its original location. 703 // EndMoveLoop is going to snap the window back to its original location.
696 // Hide it so users don't see this. 704 // Hide it so users don't see this. Hiding a window in Linux aura causes
705 // it to lose capture so skip it.
697 browser_widget->Hide(); 706 browser_widget->Hide();
707 #endif
698 browser_widget->EndMoveLoop(); 708 browser_widget->EndMoveLoop();
699 709
700 // Ideally we would always swap the tabs now, but on non-ash it seems that 710 // Ideally we would always swap the tabs now, but on non-ash it seems that
701 // running the move loop implicitly activates the window when done, leading 711 // running the move loop implicitly activates the window when done, leading
702 // to all sorts of flicker. So, on non-ash, instead we process the move 712 // to all sorts of flicker. So, on non-ash, instead we process the move
703 // after the loop completes. But on chromeos, we can do tab swapping now to 713 // after the loop completes. But on chromeos, we can do tab swapping now to
704 // avoid the tab flashing issue(crbug.com/116329). 714 // avoid the tab flashing issue(crbug.com/116329).
705 if (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH) { 715 if (use_aura_capture_policy_) {
706 is_dragging_window_ = false; 716 is_dragging_window_ = false;
707 Detach(DONT_RELEASE_CAPTURE); 717 Detach(DONT_RELEASE_CAPTURE);
708 Attach(target_tabstrip, point_in_screen); 718 Attach(target_tabstrip, point_in_screen);
709 // Move the tabs into position. 719 // Move the tabs into position.
710 MoveAttached(point_in_screen); 720 MoveAttached(point_in_screen);
711 attached_tabstrip_->GetWidget()->Activate(); 721 attached_tabstrip_->GetWidget()->Activate();
712 } else { 722 } else {
713 tab_strip_to_attach_to_after_exit_ = target_tabstrip; 723 tab_strip_to_attach_to_after_exit_ = target_tabstrip;
714 } 724 }
715 725
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs(); 1130 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs();
1121 OffsetX(GetAttachedDragPoint(point_in_screen).x(), &drag_bounds); 1131 OffsetX(GetAttachedDragPoint(point_in_screen).x(), &drag_bounds);
1122 1132
1123 gfx::Vector2d drag_offset; 1133 gfx::Vector2d drag_offset;
1124 Browser* browser = CreateBrowserForDrag( 1134 Browser* browser = CreateBrowserForDrag(
1125 attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds); 1135 attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds);
1126 #if defined(OS_WIN) 1136 #if defined(OS_WIN)
1127 gfx::NativeView attached_native_view = 1137 gfx::NativeView attached_native_view =
1128 attached_tabstrip_->GetWidget()->GetNativeView(); 1138 attached_tabstrip_->GetWidget()->GetNativeView();
1129 #endif 1139 #endif
1130 Detach(host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH ? 1140 Detach(use_aura_capture_policy_ ? DONT_RELEASE_CAPTURE : RELEASE_CAPTURE);
1131 DONT_RELEASE_CAPTURE : RELEASE_CAPTURE);
1132 BrowserView* dragged_browser_view = 1141 BrowserView* dragged_browser_view =
1133 BrowserView::GetBrowserViewForBrowser(browser); 1142 BrowserView::GetBrowserViewForBrowser(browser);
1134 views::Widget* dragged_widget = dragged_browser_view->GetWidget(); 1143 views::Widget* dragged_widget = dragged_browser_view->GetWidget();
1135 #if defined(OS_WIN) 1144 #if defined(OS_WIN)
1136 // The Gesture recognizer does not work well currently when capture changes 1145 // The Gesture recognizer does not work well currently when capture changes
1137 // while a touch gesture is in progress. So we need to manually transfer 1146 // while a touch gesture is in progress. So we need to manually transfer
1138 // gesture sequence and the GR's touch events queue to the new window. This 1147 // gesture sequence and the GR's touch events queue to the new window. This
1139 // should really be done somewhere in capture change code and or inside the 1148 // should really be done somewhere in capture change code and or inside the
1140 // GR. But we currently do not have a consistent way for doing it that would 1149 // GR. But we currently do not have a consistent way for doing it that would
1141 // work in all cases. Hence this hack. 1150 // work in all cases. Hence this hack.
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after
1897 aura::Window* dragged_window = 1906 aura::Window* dragged_window =
1898 attached_tabstrip_->GetWidget()->GetNativeView(); 1907 attached_tabstrip_->GetWidget()->GetNativeView();
1899 if (dragged_window) 1908 if (dragged_window)
1900 exclude.insert(dragged_window); 1909 exclude.insert(dragged_window);
1901 } 1910 }
1902 return GetLocalProcessWindowAtPoint(host_desktop_type_, 1911 return GetLocalProcessWindowAtPoint(host_desktop_type_,
1903 screen_point, 1912 screen_point,
1904 exclude); 1913 exclude);
1905 1914
1906 } 1915 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698