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

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

Issue 455553003: Do not release capture when starting a move loop on Desktop Linux (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
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 "ash/accelerators/accelerator_commands.h" 10 #include "ash/accelerators/accelerator_commands.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698