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

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

Issue 10828133: Desktop Aura: Allow tab drags out of window. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Better mouse tracking Created 8 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 "base/callback.h" 10 #include "base/callback.h"
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 477
478 if (!started_drag_) { 478 if (!started_drag_) {
479 if (!CanStartDrag(real_point_in_screen)) 479 if (!CanStartDrag(real_point_in_screen))
480 return; // User hasn't dragged far enough yet. 480 return; // User hasn't dragged far enough yet.
481 481
482 started_drag_ = true; 482 started_drag_ = true;
483 SaveFocus(); 483 SaveFocus();
484 Attach(source_tabstrip_, gfx::Point()); 484 Attach(source_tabstrip_, gfx::Point());
485 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) == 485 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) ==
486 GetModel(source_tabstrip_)->count()) { 486 GetModel(source_tabstrip_)->count()) {
487 RunMoveLoop(); // Runs a nested loop, returning when done. 487 gfx::Point dragged_view_point = GetWindowOffset(point_in_screen);
488 RunMoveLoop(dragged_view_point);
488 return; 489 return;
489 } 490 }
490 } 491 }
491 492
492 ContinueDragging(real_point_in_screen); 493 ContinueDragging(real_point_in_screen);
493 } 494 }
494 495
495 void TabDragController::EndDrag(bool canceled) { 496 void TabDragController::EndDrag(bool canceled) {
496 EndDragImpl(canceled && source_tabstrip_ ? CANCELED : NORMAL); 497 EndDragImpl(canceled && source_tabstrip_ ? CANCELED : NORMAL);
497 } 498 }
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 // ratio of mouse_offset_ to original width is maintained. 1160 // ratio of mouse_offset_ to original width is maintained.
1160 std::vector<BaseTab*> tabs_to_source(tabs); 1161 std::vector<BaseTab*> tabs_to_source(tabs);
1161 tabs_to_source.erase(tabs_to_source.begin() + source_tab_index_ + 1, 1162 tabs_to_source.erase(tabs_to_source.begin() + source_tab_index_ + 1,
1162 tabs_to_source.end()); 1163 tabs_to_source.end());
1163 int new_x = attached_tabstrip_->GetSizeNeededForTabs(tabs_to_source) - 1164 int new_x = attached_tabstrip_->GetSizeNeededForTabs(tabs_to_source) -
1164 tabs[source_tab_index_]->width() + 1165 tabs[source_tab_index_]->width() +
1165 static_cast<int>(offset_to_width_ratio_ * 1166 static_cast<int>(offset_to_width_ratio_ *
1166 tabs[source_tab_index_]->width()); 1167 tabs[source_tab_index_]->width());
1167 mouse_offset_.set_x(new_x); 1168 mouse_offset_.set_x(new_x);
1168 1169
1170 views::View* toplevel_view =
1171 attached_tabstrip->GetWidget()->GetContentsView();
1172 window_mouse_offset_ = point_in_screen;
1173 views::View::ConvertPointFromScreen(toplevel_view, &window_mouse_offset_);
1174
1169 // Transfer ownership of us to the new tabstrip as well as making sure the 1175 // Transfer ownership of us to the new tabstrip as well as making sure the
1170 // window has capture. This is important so that if activation changes the 1176 // window has capture. This is important so that if activation changes the
1171 // drag isn't prematurely canceled. 1177 // drag isn't prematurely canceled.
1172 if (detach_into_browser_) { 1178 if (detach_into_browser_) {
1173 attached_tabstrip_->GetWidget()->SetCapture(attached_tabstrip_); 1179 attached_tabstrip_->GetWidget()->SetCapture(attached_tabstrip_);
1174 attached_tabstrip_->OwnDragController(this); 1180 attached_tabstrip_->OwnDragController(this);
1175 } 1181 }
1176 1182
1177 // Redirect all mouse events to the TabStrip so that the tab that originated 1183 // Redirect all mouse events to the TabStrip so that the tab that originated
1178 // the drag can safely be deleted. 1184 // the drag can safely be deleted.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 attached_tabstrip_ = NULL; 1265 attached_tabstrip_ = NULL;
1260 } 1266 }
1261 1267
1262 void TabDragController::DetachIntoNewBrowserAndRunMoveLoop( 1268 void TabDragController::DetachIntoNewBrowserAndRunMoveLoop(
1263 const gfx::Point& point_in_screen) { 1269 const gfx::Point& point_in_screen) {
1264 if (GetModel(attached_tabstrip_)->count() == 1270 if (GetModel(attached_tabstrip_)->count() ==
1265 static_cast<int>(drag_data_.size())) { 1271 static_cast<int>(drag_data_.size())) {
1266 // All the tabs in a browser are being dragged but all the tabs weren't 1272 // All the tabs in a browser are being dragged but all the tabs weren't
1267 // initially being dragged. For this to happen the user would have to 1273 // initially being dragged. For this to happen the user would have to
1268 // start dragging a set of tabs, the other tabs close, then detach. 1274 // start dragging a set of tabs, the other tabs close, then detach.
1269 RunMoveLoop(); 1275 gfx::Point dragged_view_point = GetWindowOffset(point_in_screen);
1276 RunMoveLoop(dragged_view_point);
1270 return; 1277 return;
1271 } 1278 }
1272 1279
1273 // Create a new browser to house the dragged tabs and have the OS run a move 1280 // Create a new browser to house the dragged tabs and have the OS run a move
1274 // loop. 1281 // loop.
1275 1282
1276 gfx::Point attached_point = GetAttachedDragPoint(point_in_screen); 1283 gfx::Point attached_point = GetAttachedDragPoint(point_in_screen);
1277 1284
1278 // Calculate the bounds for the tabs from the attached_tab_strip. We do this 1285 // Calculate the bounds for the tabs from the attached_tab_strip. We do this
1279 // so that the tabs don't change size when detached. 1286 // so that the tabs don't change size when detached.
1280 std::vector<gfx::Rect> drag_bounds = 1287 std::vector<gfx::Rect> drag_bounds =
1281 CalculateBoundsForDraggedTabs(attached_point.x()); 1288 CalculateBoundsForDraggedTabs(attached_point.x());
1282 1289
1290 gfx::Point drag_offset;
1283 Browser* browser = CreateBrowserForDrag( 1291 Browser* browser = CreateBrowserForDrag(
1284 attached_tabstrip_, point_in_screen, &drag_bounds); 1292 attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds);
1285 Detach(DONT_RELEASE_CAPTURE); 1293 Detach(DONT_RELEASE_CAPTURE);
1286 BrowserView* dragged_browser_view = 1294 BrowserView* dragged_browser_view =
1287 BrowserView::GetBrowserViewForBrowser(browser); 1295 BrowserView::GetBrowserViewForBrowser(browser);
1288 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( 1296 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled(
1289 false); 1297 false);
1290 Attach(dragged_browser_view->tabstrip(), gfx::Point()); 1298 Attach(dragged_browser_view->tabstrip(), gfx::Point());
1291 // TODO: come up with a cleaner way to do this. 1299 // TODO: come up with a cleaner way to do this.
1292 attached_tabstrip_->SetTabBoundsForDrag(drag_bounds); 1300 attached_tabstrip_->SetTabBoundsForDrag(drag_bounds);
1293 1301
1294 browser->window()->Show(); 1302 browser->window()->Show();
1295 browser->window()->Activate(); 1303 browser->window()->Activate();
1296 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( 1304 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled(
1297 true); 1305 true);
1298 RunMoveLoop(); 1306 RunMoveLoop(drag_offset);
1299 } 1307 }
1300 1308
1301 void TabDragController::RunMoveLoop() { 1309 void TabDragController::RunMoveLoop(const gfx::Point& drag_offset) {
1302 // If the user drags the whole window we'll assume they are going to attach to 1310 // If the user drags the whole window we'll assume they are going to attach to
1303 // another window and therefor want to reorder. 1311 // another window and therefor want to reorder.
1304 move_behavior_ = REORDER; 1312 move_behavior_ = REORDER;
1305 1313
1306 move_loop_widget_ = GetAttachedBrowserWidget(); 1314 move_loop_widget_ = GetAttachedBrowserWidget();
1307 DCHECK(move_loop_widget_); 1315 DCHECK(move_loop_widget_);
1308 move_loop_widget_->AddObserver(this); 1316 move_loop_widget_->AddObserver(this);
1309 is_dragging_window_ = true; 1317 is_dragging_window_ = true;
1310 bool destroyed = false; 1318 bool destroyed = false;
1311 destroyed_ = &destroyed; 1319 destroyed_ = &destroyed;
1312 #if !defined(USE_ASH) 1320 #if !defined(USE_ASH)
1313 // Running the move loop releases mouse capture on Windows, which triggers 1321 // Running the move loop releases mouse capture on Windows, which triggers
1314 // destroying the drag loop. Release mouse capture ourself before this while 1322 // destroying the drag loop. Release mouse capture ourself before this while
1315 // the DragController isn't owned by the TabStrip. 1323 // the DragController isn't owned by the TabStrip.
1316 attached_tabstrip_->ReleaseDragController(); 1324 attached_tabstrip_->ReleaseDragController();
1317 attached_tabstrip_->GetWidget()->ReleaseCapture(); 1325 attached_tabstrip_->GetWidget()->ReleaseCapture();
1318 attached_tabstrip_->OwnDragController(this); 1326 attached_tabstrip_->OwnDragController(this);
1319 #endif 1327 #endif
1320 views::Widget::MoveLoopResult result = move_loop_widget_->RunMoveLoop(); 1328 views::Widget::MoveLoopResult result =
1329 move_loop_widget_->RunMoveLoop(drag_offset);
1321 content::NotificationService::current()->Notify( 1330 content::NotificationService::current()->Notify(
1322 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, 1331 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE,
1323 content::NotificationService::AllBrowserContextsAndSources(), 1332 content::NotificationService::AllBrowserContextsAndSources(),
1324 content::NotificationService::NoDetails()); 1333 content::NotificationService::NoDetails());
1325 1334
1326 if (destroyed) 1335 if (destroyed)
1327 return; 1336 return;
1328 destroyed_ = NULL; 1337 destroyed_ = NULL;
1329 // Under chromeos we immediately set the |move_loop_widget_| to NULL. 1338 // Under chromeos we immediately set the |move_loop_widget_| to NULL.
1330 if (move_loop_widget_) { 1339 if (move_loop_widget_) {
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
1908 drag_data_[i].source_model_index) { 1917 drag_data_[i].source_model_index) {
1909 return false; 1918 return false;
1910 } 1919 }
1911 } 1920 }
1912 return true; 1921 return true;
1913 } 1922 }
1914 1923
1915 Browser* TabDragController::CreateBrowserForDrag( 1924 Browser* TabDragController::CreateBrowserForDrag(
1916 TabStrip* source, 1925 TabStrip* source,
1917 const gfx::Point& point_in_screen, 1926 const gfx::Point& point_in_screen,
1927 gfx::Point* drag_offset,
1918 std::vector<gfx::Rect>* drag_bounds) { 1928 std::vector<gfx::Rect>* drag_bounds) {
1919 Browser* browser = new Browser( 1929 Browser* browser = new Browser(
1920 Browser::CreateParams(drag_data_[0].contents->profile())); 1930 Browser::CreateParams(drag_data_[0].contents->profile()));
1921 gfx::Point center(0, source->height() / 2); 1931 gfx::Point center(0, source->height() / 2);
1922 views::View::ConvertPointToWidget(source, &center); 1932 views::View::ConvertPointToWidget(source, &center);
1923 gfx::Rect new_bounds(source->GetWidget()->GetWindowBoundsInScreen()); 1933 gfx::Rect new_bounds(source->GetWidget()->GetWindowBoundsInScreen());
1924 new_bounds.set_y(point_in_screen.y() - center.y()); 1934 new_bounds.set_y(point_in_screen.y() - center.y());
1925 switch (GetDetachPosition(point_in_screen)) { 1935 switch (GetDetachPosition(point_in_screen)) {
1926 case DETACH_BEFORE: 1936 case DETACH_BEFORE:
1927 new_bounds.set_x(point_in_screen.x() - center.x()); 1937 new_bounds.set_x(point_in_screen.x() - center.x());
1928 new_bounds.Offset(-mouse_offset_.x(), 0); 1938 new_bounds.Offset(-mouse_offset_.x(), 0);
1929 break; 1939 break;
1930 1940
1931 case DETACH_AFTER: { 1941 case DETACH_AFTER: {
1932 gfx::Point right_edge(source->width(), 0); 1942 gfx::Point right_edge(source->width(), 0);
1933 views::View::ConvertPointToWidget(source, &right_edge); 1943 views::View::ConvertPointToWidget(source, &right_edge);
1934 new_bounds.set_x(point_in_screen.x() - right_edge.x()); 1944 new_bounds.set_x(point_in_screen.x() - right_edge.x());
1935 new_bounds.Offset(drag_bounds->back().right() - mouse_offset_.x(), 0); 1945 new_bounds.Offset(drag_bounds->back().right() - mouse_offset_.x(), 0);
1936 int delta = (*drag_bounds)[0].x(); 1946 int delta = (*drag_bounds)[0].x();
1937 for (size_t i = 0; i < drag_bounds->size(); ++i) 1947 for (size_t i = 0; i < drag_bounds->size(); ++i)
1938 (*drag_bounds)[i].Offset(-delta, 0); 1948 (*drag_bounds)[i].Offset(-delta, 0);
1939 break; 1949 break;
1940 } 1950 }
1941 1951
1942 default: 1952 default:
1943 break; // Nothing to do for DETACH_ABOVE_OR_BELOW. 1953 break; // Nothing to do for DETACH_ABOVE_OR_BELOW.
1944 } 1954 }
1945 1955
1956 *drag_offset = point_in_screen.Subtract(new_bounds.origin());
1957
1946 SetTrackedByWorkspace(browser->window()->GetNativeWindow(), false); 1958 SetTrackedByWorkspace(browser->window()->GetNativeWindow(), false);
1947 browser->window()->SetBounds(new_bounds); 1959 browser->window()->SetBounds(new_bounds);
1948 return browser; 1960 return browser;
1949 } 1961 }
1950 1962
1951 gfx::Point TabDragController::GetCursorScreenPoint() { 1963 gfx::Point TabDragController::GetCursorScreenPoint() {
1952 #if defined(USE_ASH) 1964 #if defined(USE_ASH)
1953 views::Widget* widget = GetAttachedBrowserWidget(); 1965 views::Widget* widget = GetAttachedBrowserWidget();
1954 DCHECK(widget); 1966 DCHECK(widget);
1955 if (aura::Env::GetInstance()->is_touch_down()) { 1967 if (aura::Env::GetInstance()->is_touch_down()) {
1956 aura::Window* widget_window = widget->GetNativeWindow(); 1968 aura::Window* widget_window = widget->GetNativeWindow();
1957 DCHECK(widget_window->GetRootWindow()); 1969 DCHECK(widget_window->GetRootWindow());
1958 gfx::Point touch_point; 1970 gfx::Point touch_point;
1959 bool got_touch_point = widget_window->GetRootWindow()-> 1971 bool got_touch_point = widget_window->GetRootWindow()->
1960 gesture_recognizer()->GetLastTouchPointForTarget(widget_window, 1972 gesture_recognizer()->GetLastTouchPointForTarget(widget_window,
1961 &touch_point); 1973 &touch_point);
1962 DCHECK(got_touch_point); 1974 DCHECK(got_touch_point);
1963 return touch_point; 1975 return touch_point;
1964 } 1976 }
1965 #endif 1977 #endif
1966 return gfx::Screen::GetCursorScreenPoint(); 1978 return gfx::Screen::GetCursorScreenPoint();
1967 } 1979 }
1980
1981 gfx::Point TabDragController::GetWindowOffset(
1982 const gfx::Point& point_in_screen) {
1983 TabStrip* owning_tabstrip = (attached_tabstrip_ && detach_into_browser_) ?
1984 attached_tabstrip_ : source_tabstrip_;
1985 views::View* toplevel_view = owning_tabstrip->GetWidget()->GetContentsView();
1986
1987 gfx::Point offset = point_in_screen;
1988 views::View::ConvertPointFromScreen(toplevel_view, &offset);
1989 return offset;
1990 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698