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

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, 3 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 "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 174
175 // static 175 // static
176 const int TabDragController::kVerticalDetachMagnetism = 15; 176 const int TabDragController::kVerticalDetachMagnetism = 15;
177 177
178 TabDragController::TabDragController() 178 TabDragController::TabDragController()
179 : event_source_(EVENT_SOURCE_MOUSE), 179 : event_source_(EVENT_SOURCE_MOUSE),
180 source_tabstrip_(NULL), 180 source_tabstrip_(NULL),
181 attached_tabstrip_(NULL), 181 attached_tabstrip_(NULL),
182 screen_(NULL), 182 screen_(NULL),
183 host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE), 183 host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE),
184 use_aura_capture_policy_(false), 184 can_release_capture_(true),
185 offset_to_width_ratio_(0), 185 offset_to_width_ratio_(0),
186 old_focused_view_id_( 186 old_focused_view_id_(
187 views::ViewStorage::GetInstance()->CreateStorageID()), 187 views::ViewStorage::GetInstance()->CreateStorageID()),
188 last_move_screen_loc_(0), 188 last_move_screen_loc_(0),
189 started_drag_(false), 189 started_drag_(false),
190 active_(true), 190 active_(true),
191 source_tab_index_(std::numeric_limits<size_t>::max()), 191 source_tab_index_(std::numeric_limits<size_t>::max()),
192 initial_move_(true), 192 initial_move_(true),
193 detach_behavior_(DETACHABLE), 193 detach_behavior_(DETACHABLE),
194 move_behavior_(REORDER), 194 move_behavior_(REORDER),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 EventSource event_source) { 241 EventSource event_source) {
242 DCHECK(!tabs.empty()); 242 DCHECK(!tabs.empty());
243 DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end()); 243 DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end());
244 source_tabstrip_ = source_tabstrip; 244 source_tabstrip_ = source_tabstrip;
245 was_source_maximized_ = source_tabstrip->GetWidget()->IsMaximized(); 245 was_source_maximized_ = source_tabstrip->GetWidget()->IsMaximized();
246 was_source_fullscreen_ = source_tabstrip->GetWidget()->IsFullscreen(); 246 was_source_fullscreen_ = source_tabstrip->GetWidget()->IsFullscreen();
247 screen_ = gfx::Screen::GetScreenFor( 247 screen_ = gfx::Screen::GetScreenFor(
248 source_tabstrip->GetWidget()->GetNativeView()); 248 source_tabstrip->GetWidget()->GetNativeView());
249 host_desktop_type_ = chrome::GetHostDesktopTypeForNativeView( 249 host_desktop_type_ = chrome::GetHostDesktopTypeForNativeView(
250 source_tabstrip->GetWidget()->GetNativeView()); 250 source_tabstrip->GetWidget()->GetNativeView());
251 // Do not release capture when transferring capture between widgets on:
252 // - Desktop Linux
253 // Mouse capture is not synchronous on desktop Linux. Chrome makes
254 // transferring capture between widgets without releasing capture appear
255 // synchronous on desktop Linux, so use that.
256 // - Ash
257 // Releasing capture on Ash cancels gestures so avoid it.
251 #if defined(OS_LINUX) 258 #if defined(OS_LINUX)
252 use_aura_capture_policy_ = true; 259 can_release_capture_ = false;
253 #else 260 #else
254 use_aura_capture_policy_ = 261 can_release_capture_ =
255 (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH); 262 (host_desktop_type_ != chrome::HOST_DESKTOP_TYPE_ASH);
256 #endif 263 #endif
257 start_point_in_screen_ = gfx::Point(source_tab_offset, mouse_offset.y()); 264 start_point_in_screen_ = gfx::Point(source_tab_offset, mouse_offset.y());
258 views::View::ConvertPointToScreen(source_tab, &start_point_in_screen_); 265 views::View::ConvertPointToScreen(source_tab, &start_point_in_screen_);
259 event_source_ = event_source; 266 event_source_ = event_source;
260 mouse_offset_ = mouse_offset; 267 mouse_offset_ = mouse_offset;
261 move_behavior_ = move_behavior; 268 move_behavior_ = move_behavior;
262 last_point_in_screen_ = start_point_in_screen_; 269 last_point_in_screen_ = start_point_in_screen_;
263 last_move_screen_loc_ = start_point_in_screen_.x(); 270 last_move_screen_loc_ = start_point_in_screen_.x();
264 initial_tab_positions_ = source_tabstrip->GetTabXCoordinates(); 271 initial_tab_positions_ = source_tabstrip->GetTabXCoordinates();
265 272
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 "point_in_screen", point_in_screen.ToString()); 572 "point_in_screen", point_in_screen.ToString());
566 573
567 if (!target_tabstrip) { 574 if (!target_tabstrip) {
568 DetachIntoNewBrowserAndRunMoveLoop(point_in_screen); 575 DetachIntoNewBrowserAndRunMoveLoop(point_in_screen);
569 return DRAG_BROWSER_RESULT_STOP; 576 return DRAG_BROWSER_RESULT_STOP;
570 } 577 }
571 if (is_dragging_window_) { 578 if (is_dragging_window_) {
572 // ReleaseCapture() is going to result in calling back to us (because it 579 // ReleaseCapture() is going to result in calling back to us (because it
573 // results in a move). That'll cause all sorts of problems. Reset the 580 // results in a move). That'll cause all sorts of problems. Reset the
574 // observer so we don't get notified and process the event. 581 // observer so we don't get notified and process the event.
575 if (use_aura_capture_policy_) { 582 if (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH) {
576 move_loop_widget_->RemoveObserver(this); 583 move_loop_widget_->RemoveObserver(this);
577 move_loop_widget_ = NULL; 584 move_loop_widget_ = NULL;
578 } 585 }
579 views::Widget* browser_widget = GetAttachedBrowserWidget(); 586 views::Widget* browser_widget = GetAttachedBrowserWidget();
580 // Need to release the drag controller before starting the move loop as it's 587 // Need to release the drag controller before starting the move loop as it's
581 // going to trigger capture lost, which cancels drag. 588 // going to trigger capture lost, which cancels drag.
582 attached_tabstrip_->ReleaseDragController(); 589 attached_tabstrip_->ReleaseDragController();
583 target_tabstrip->OwnDragController(this); 590 target_tabstrip->OwnDragController(this);
584 // Disable animations so that we don't see a close animation on aero. 591 // Disable animations so that we don't see a close animation on aero.
585 browser_widget->SetVisibilityChangedAnimationsEnabled(false); 592 browser_widget->SetVisibilityChangedAnimationsEnabled(false);
586 // For aura we can't release capture, otherwise it'll cancel a gesture. 593 if (can_release_capture_)
587 // Instead we have to directly change capture. 594 browser_widget->ReleaseCapture();
588 if (use_aura_capture_policy_) 595 else
589 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_); 596 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_);
590 else
591 browser_widget->ReleaseCapture();
592 #if defined(OS_WIN) 597 #if defined(OS_WIN)
593 // The Gesture recognizer does not work well currently when capture changes 598 // The Gesture recognizer does not work well currently when capture changes
594 // while a touch gesture is in progress. So we need to manually transfer 599 // while a touch gesture is in progress. So we need to manually transfer
595 // gesture sequence and the GR's touch events queue to the new window. This 600 // gesture sequence and the GR's touch events queue to the new window. This
596 // should really be done somewhere in capture change code and or inside the 601 // should really be done somewhere in capture change code and or inside the
597 // GR. But we currently do not have a consistent way for doing it that would 602 // GR. But we currently do not have a consistent way for doing it that would
598 // work in all cases. Hence this hack. 603 // work in all cases. Hence this hack.
599 ui::GestureRecognizer::Get()->TransferEventsTo( 604 ui::GestureRecognizer::Get()->TransferEventsTo(
600 browser_widget->GetNativeView(), 605 browser_widget->GetNativeView(),
601 target_tabstrip->GetWidget()->GetNativeView()); 606 target_tabstrip->GetWidget()->GetNativeView());
602 #endif 607 #endif
603 608
604 // The window is going away. Since the drag is still on going we don't want 609 // The window is going away. Since the drag is still on going we don't want
605 // that to effect the position of any windows. 610 // that to effect the position of any windows.
606 SetWindowPositionManaged(browser_widget->GetNativeView(), false); 611 SetWindowPositionManaged(browser_widget->GetNativeView(), false);
607 612
608 #if !defined(OS_LINUX) || defined(OS_CHROMEOS) 613 #if !defined(OS_LINUX) || defined(OS_CHROMEOS)
609 // EndMoveLoop is going to snap the window back to its original location. 614 // EndMoveLoop is going to snap the window back to its original location.
610 // Hide it so users don't see this. Hiding a window in Linux aura causes 615 // Hide it so users don't see this. Hiding a window in Linux aura causes
611 // it to lose capture so skip it. 616 // it to lose capture so skip it.
612 browser_widget->Hide(); 617 browser_widget->Hide();
613 #endif 618 #endif
614 browser_widget->EndMoveLoop(); 619 browser_widget->EndMoveLoop();
615 620
616 // Ideally we would always swap the tabs now, but on non-ash it seems that 621 // Ideally we would always swap the tabs now, but on non-ash Windows, it
617 // running the move loop implicitly activates the window when done, leading 622 // seems that running the move loop implicitly activates the window when
618 // to all sorts of flicker. So, on non-ash, instead we process the move 623 // done, leading to all sorts of flicker. So, on non-ash Windows, instead
619 // after the loop completes. But on chromeos, we can do tab swapping now to 624 // we process the move after the loop completes. But on chromeos, we can
620 // avoid the tab flashing issue(crbug.com/116329). 625 // do tab swapping now to avoid the tab flashing issue
621 if (use_aura_capture_policy_) { 626 // (crbug.com/116329).
627 if (can_release_capture_) {
628 tab_strip_to_attach_to_after_exit_ = target_tabstrip;
629 } else {
622 is_dragging_window_ = false; 630 is_dragging_window_ = false;
623 Detach(DONT_RELEASE_CAPTURE); 631 Detach(DONT_RELEASE_CAPTURE);
624 Attach(target_tabstrip, point_in_screen); 632 Attach(target_tabstrip, point_in_screen);
625 // Move the tabs into position. 633 // Move the tabs into position.
626 MoveAttached(point_in_screen); 634 MoveAttached(point_in_screen);
627 attached_tabstrip_->GetWidget()->Activate(); 635 attached_tabstrip_->GetWidget()->Activate();
628 } else {
629 tab_strip_to_attach_to_after_exit_ = target_tabstrip;
630 } 636 }
631 637
632 waiting_for_run_loop_to_exit_ = true; 638 waiting_for_run_loop_to_exit_ = true;
633 end_run_loop_behavior_ = END_RUN_LOOP_CONTINUE_DRAGGING; 639 end_run_loop_behavior_ = END_RUN_LOOP_CONTINUE_DRAGGING;
634 return DRAG_BROWSER_RESULT_STOP; 640 return DRAG_BROWSER_RESULT_STOP;
635 } 641 }
636 Detach(DONT_RELEASE_CAPTURE); 642 Detach(DONT_RELEASE_CAPTURE);
637 Attach(target_tabstrip, point_in_screen); 643 Attach(target_tabstrip, point_in_screen);
638 return DRAG_BROWSER_RESULT_CONTINUE; 644 return DRAG_BROWSER_RESULT_CONTINUE;
639 } 645 }
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs(); 1014 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs();
1009 OffsetX(GetAttachedDragPoint(point_in_screen).x(), &drag_bounds); 1015 OffsetX(GetAttachedDragPoint(point_in_screen).x(), &drag_bounds);
1010 1016
1011 gfx::Vector2d drag_offset; 1017 gfx::Vector2d drag_offset;
1012 Browser* browser = CreateBrowserForDrag( 1018 Browser* browser = CreateBrowserForDrag(
1013 attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds); 1019 attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds);
1014 #if defined(OS_WIN) 1020 #if defined(OS_WIN)
1015 gfx::NativeView attached_native_view = 1021 gfx::NativeView attached_native_view =
1016 attached_tabstrip_->GetWidget()->GetNativeView(); 1022 attached_tabstrip_->GetWidget()->GetNativeView();
1017 #endif 1023 #endif
1018 Detach(use_aura_capture_policy_ ? DONT_RELEASE_CAPTURE : RELEASE_CAPTURE); 1024 Detach(can_release_capture_ ? RELEASE_CAPTURE : DONT_RELEASE_CAPTURE);
1019 BrowserView* dragged_browser_view = 1025 BrowserView* dragged_browser_view =
1020 BrowserView::GetBrowserViewForBrowser(browser); 1026 BrowserView::GetBrowserViewForBrowser(browser);
1021 views::Widget* dragged_widget = dragged_browser_view->GetWidget(); 1027 views::Widget* dragged_widget = dragged_browser_view->GetWidget();
1022 #if defined(OS_WIN) 1028 #if defined(OS_WIN)
1023 // The Gesture recognizer does not work well currently when capture changes 1029 // The Gesture recognizer does not work well currently when capture changes
1024 // while a touch gesture is in progress. So we need to manually transfer 1030 // while a touch gesture is in progress. So we need to manually transfer
1025 // gesture sequence and the GR's touch events queue to the new window. This 1031 // gesture sequence and the GR's touch events queue to the new window. This
1026 // should really be done somewhere in capture change code and or inside the 1032 // should really be done somewhere in capture change code and or inside the
1027 // GR. But we currently do not have a consistent way for doing it that would 1033 // GR. But we currently do not have a consistent way for doing it that would
1028 // work in all cases. Hence this hack. 1034 // work in all cases. Hence this hack.
(...skipping 24 matching lines...) Expand all
1053 void TabDragController::RunMoveLoop(const gfx::Vector2d& drag_offset) { 1059 void TabDragController::RunMoveLoop(const gfx::Vector2d& drag_offset) {
1054 // If the user drags the whole window we'll assume they are going to attach to 1060 // If the user drags the whole window we'll assume they are going to attach to
1055 // another window and therefore want to reorder. 1061 // another window and therefore want to reorder.
1056 move_behavior_ = REORDER; 1062 move_behavior_ = REORDER;
1057 1063
1058 move_loop_widget_ = GetAttachedBrowserWidget(); 1064 move_loop_widget_ = GetAttachedBrowserWidget();
1059 DCHECK(move_loop_widget_); 1065 DCHECK(move_loop_widget_);
1060 move_loop_widget_->AddObserver(this); 1066 move_loop_widget_->AddObserver(this);
1061 is_dragging_window_ = true; 1067 is_dragging_window_ = true;
1062 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); 1068 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr());
1063 // Running the move loop releases mouse capture on non-ash, which triggers 1069 if (can_release_capture_) {
1064 // destroying the drag loop. Release mouse capture ourself before this while 1070 // Running the move loop releases mouse capture, which triggers destroying
1065 // the DragController isn't owned by the TabStrip. 1071 // the drag loop. Release mouse capture now while the DragController is not
1066 if (host_desktop_type_ != chrome::HOST_DESKTOP_TYPE_ASH) { 1072 // owned by the TabStrip.
1067 attached_tabstrip_->ReleaseDragController(); 1073 attached_tabstrip_->ReleaseDragController();
1068 attached_tabstrip_->GetWidget()->ReleaseCapture(); 1074 attached_tabstrip_->GetWidget()->ReleaseCapture();
1069 attached_tabstrip_->OwnDragController(this); 1075 attached_tabstrip_->OwnDragController(this);
1070 } 1076 }
1071 const views::Widget::MoveLoopSource move_loop_source = 1077 const views::Widget::MoveLoopSource move_loop_source =
1072 event_source_ == EVENT_SOURCE_MOUSE ? 1078 event_source_ == EVENT_SOURCE_MOUSE ?
1073 views::Widget::MOVE_LOOP_SOURCE_MOUSE : 1079 views::Widget::MOVE_LOOP_SOURCE_MOUSE :
1074 views::Widget::MOVE_LOOP_SOURCE_TOUCH; 1080 views::Widget::MOVE_LOOP_SOURCE_TOUCH;
1075 const views::Widget::MoveLoopEscapeBehavior escape_behavior = 1081 const views::Widget::MoveLoopEscapeBehavior escape_behavior =
1076 is_dragging_new_browser_ ? 1082 is_dragging_new_browser_ ?
1077 views::Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_HIDE : 1083 views::Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_HIDE :
1078 views::Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_DONT_HIDE; 1084 views::Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_DONT_HIDE;
1079 views::Widget::MoveLoopResult result = 1085 views::Widget::MoveLoopResult result =
1080 move_loop_widget_->RunMoveLoop( 1086 move_loop_widget_->RunMoveLoop(
1081 drag_offset, move_loop_source, escape_behavior); 1087 drag_offset, move_loop_source, escape_behavior);
1082 content::NotificationService::current()->Notify( 1088 content::NotificationService::current()->Notify(
1083 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, 1089 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE,
1084 content::NotificationService::AllBrowserContextsAndSources(), 1090 content::NotificationService::AllBrowserContextsAndSources(),
1085 content::NotificationService::NoDetails()); 1091 content::NotificationService::NoDetails());
1086 1092
1087 if (!ref) 1093 if (!ref)
1088 return; 1094 return;
1089 // Under chromeos we immediately set the |move_loop_widget_| to NULL.
1090 if (move_loop_widget_) { 1095 if (move_loop_widget_) {
1091 move_loop_widget_->RemoveObserver(this); 1096 move_loop_widget_->RemoveObserver(this);
1092 move_loop_widget_ = NULL; 1097 move_loop_widget_ = NULL;
1093 } 1098 }
1094 is_dragging_window_ = false; 1099 is_dragging_window_ = false;
1095 waiting_for_run_loop_to_exit_ = false; 1100 waiting_for_run_loop_to_exit_ = false;
1096 if (end_run_loop_behavior_ == END_RUN_LOOP_CONTINUE_DRAGGING) { 1101 if (end_run_loop_behavior_ == END_RUN_LOOP_CONTINUE_DRAGGING) {
1097 end_run_loop_behavior_ = END_RUN_LOOP_STOP_DRAGGING; 1102 end_run_loop_behavior_ = END_RUN_LOOP_STOP_DRAGGING;
1098 if (tab_strip_to_attach_to_after_exit_) { 1103 if (tab_strip_to_attach_to_after_exit_) {
1099 gfx::Point point_in_screen(GetCursorScreenPoint()); 1104 gfx::Point point_in_screen(GetCursorScreenPoint());
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 it != browser_list->end(); ++it) { 1785 it != browser_list->end(); ++it) {
1781 if ((*it)->tab_strip_model()->empty()) 1786 if ((*it)->tab_strip_model()->empty())
1782 exclude.insert((*it)->window()->GetNativeWindow()); 1787 exclude.insert((*it)->window()->GetNativeWindow());
1783 } 1788 }
1784 #endif 1789 #endif
1785 return GetLocalProcessWindowAtPoint(host_desktop_type_, 1790 return GetLocalProcessWindowAtPoint(host_desktop_type_,
1786 screen_point, 1791 screen_point,
1787 exclude); 1792 exclude);
1788 1793
1789 } 1794 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/tabs/tab_drag_controller.h ('k') | ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698