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

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: Cleanup 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
« no previous file with comments | « chrome/browser/ui/views/tabs/tab_drag_controller.h ('k') | ui/aura/client/window_move_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 476
477 if (!started_drag_) { 477 if (!started_drag_) {
478 if (!CanStartDrag(real_point_in_screen)) 478 if (!CanStartDrag(real_point_in_screen))
479 return; // User hasn't dragged far enough yet. 479 return; // User hasn't dragged far enough yet.
480 480
481 started_drag_ = true; 481 started_drag_ = true;
482 SaveFocus(); 482 SaveFocus();
483 Attach(source_tabstrip_, gfx::Point()); 483 Attach(source_tabstrip_, gfx::Point());
484 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) == 484 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) ==
485 GetModel(source_tabstrip_)->count()) { 485 GetModel(source_tabstrip_)->count()) {
486 RunMoveLoop(); // Runs a nested loop, returning when done. 486 gfx::Point dragged_view_point = GetWindowOffset(point_in_screen);
487 RunMoveLoop(dragged_view_point);
487 return; 488 return;
488 } 489 }
489 } 490 }
490 491
491 ContinueDragging(real_point_in_screen); 492 ContinueDragging(real_point_in_screen);
492 } 493 }
493 494
494 void TabDragController::EndDrag(bool canceled) { 495 void TabDragController::EndDrag(bool canceled) {
495 EndDragImpl(canceled && source_tabstrip_ ? CANCELED : NORMAL); 496 EndDragImpl(canceled && source_tabstrip_ ? CANCELED : NORMAL);
496 } 497 }
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 attached_tabstrip_ = NULL; 1259 attached_tabstrip_ = NULL;
1259 } 1260 }
1260 1261
1261 void TabDragController::DetachIntoNewBrowserAndRunMoveLoop( 1262 void TabDragController::DetachIntoNewBrowserAndRunMoveLoop(
1262 const gfx::Point& point_in_screen) { 1263 const gfx::Point& point_in_screen) {
1263 if (GetModel(attached_tabstrip_)->count() == 1264 if (GetModel(attached_tabstrip_)->count() ==
1264 static_cast<int>(drag_data_.size())) { 1265 static_cast<int>(drag_data_.size())) {
1265 // All the tabs in a browser are being dragged but all the tabs weren't 1266 // All the tabs in a browser are being dragged but all the tabs weren't
1266 // initially being dragged. For this to happen the user would have to 1267 // initially being dragged. For this to happen the user would have to
1267 // start dragging a set of tabs, the other tabs close, then detach. 1268 // start dragging a set of tabs, the other tabs close, then detach.
1268 RunMoveLoop(); 1269 gfx::Point dragged_view_point = GetWindowOffset(point_in_screen);
1270 RunMoveLoop(dragged_view_point);
1269 return; 1271 return;
1270 } 1272 }
1271 1273
1272 // Create a new browser to house the dragged tabs and have the OS run a move 1274 // Create a new browser to house the dragged tabs and have the OS run a move
1273 // loop. 1275 // loop.
1274 1276
1275 gfx::Point attached_point = GetAttachedDragPoint(point_in_screen); 1277 gfx::Point attached_point = GetAttachedDragPoint(point_in_screen);
1276 1278
1277 // Calculate the bounds for the tabs from the attached_tab_strip. We do this 1279 // Calculate the bounds for the tabs from the attached_tab_strip. We do this
1278 // so that the tabs don't change size when detached. 1280 // so that the tabs don't change size when detached.
1279 std::vector<gfx::Rect> drag_bounds = 1281 std::vector<gfx::Rect> drag_bounds =
1280 CalculateBoundsForDraggedTabs(attached_point.x()); 1282 CalculateBoundsForDraggedTabs(attached_point.x());
1281 1283
1284 gfx::Point drag_offset;
1282 Browser* browser = CreateBrowserForDrag( 1285 Browser* browser = CreateBrowserForDrag(
1283 attached_tabstrip_, point_in_screen, &drag_bounds); 1286 attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds);
1284 Detach(DONT_RELEASE_CAPTURE); 1287 Detach(DONT_RELEASE_CAPTURE);
1285 BrowserView* dragged_browser_view = 1288 BrowserView* dragged_browser_view =
1286 BrowserView::GetBrowserViewForBrowser(browser); 1289 BrowserView::GetBrowserViewForBrowser(browser);
1287 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( 1290 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled(
1288 false); 1291 false);
1289 Attach(dragged_browser_view->tabstrip(), gfx::Point()); 1292 Attach(dragged_browser_view->tabstrip(), gfx::Point());
1290 // TODO: come up with a cleaner way to do this. 1293 // TODO: come up with a cleaner way to do this.
1291 attached_tabstrip_->SetTabBoundsForDrag(drag_bounds); 1294 attached_tabstrip_->SetTabBoundsForDrag(drag_bounds);
1292 1295
1293 browser->window()->Show(); 1296 browser->window()->Show();
1294 browser->window()->Activate(); 1297 browser->window()->Activate();
1295 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( 1298 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled(
1296 true); 1299 true);
1297 RunMoveLoop(); 1300 RunMoveLoop(drag_offset);
1298 } 1301 }
1299 1302
1300 void TabDragController::RunMoveLoop() { 1303 void TabDragController::RunMoveLoop(const gfx::Point& drag_offset) {
1301 // If the user drags the whole window we'll assume they are going to attach to 1304 // If the user drags the whole window we'll assume they are going to attach to
1302 // another window and therefor want to reorder. 1305 // another window and therefor want to reorder.
1303 move_behavior_ = REORDER; 1306 move_behavior_ = REORDER;
1304 1307
1305 move_loop_widget_ = GetAttachedBrowserWidget(); 1308 move_loop_widget_ = GetAttachedBrowserWidget();
1306 DCHECK(move_loop_widget_); 1309 DCHECK(move_loop_widget_);
1307 move_loop_widget_->AddObserver(this); 1310 move_loop_widget_->AddObserver(this);
1308 is_dragging_window_ = true; 1311 is_dragging_window_ = true;
1309 bool destroyed = false; 1312 bool destroyed = false;
1310 destroyed_ = &destroyed; 1313 destroyed_ = &destroyed;
1311 #if !defined(USE_ASH) 1314 #if !defined(USE_ASH)
1312 // Running the move loop releases mouse capture on Windows, which triggers 1315 // Running the move loop releases mouse capture on Windows, which triggers
1313 // destroying the drag loop. Release mouse capture ourself before this while 1316 // destroying the drag loop. Release mouse capture ourself before this while
1314 // the DragController isn't owned by the TabStrip. 1317 // the DragController isn't owned by the TabStrip.
1315 attached_tabstrip_->ReleaseDragController(); 1318 attached_tabstrip_->ReleaseDragController();
1316 attached_tabstrip_->GetWidget()->ReleaseCapture(); 1319 attached_tabstrip_->GetWidget()->ReleaseCapture();
1317 attached_tabstrip_->OwnDragController(this); 1320 attached_tabstrip_->OwnDragController(this);
1318 #endif 1321 #endif
1319 views::Widget::MoveLoopResult result = move_loop_widget_->RunMoveLoop(); 1322 views::Widget::MoveLoopResult result =
1323 move_loop_widget_->RunMoveLoop(drag_offset);
1320 content::NotificationService::current()->Notify( 1324 content::NotificationService::current()->Notify(
1321 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, 1325 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE,
1322 content::NotificationService::AllBrowserContextsAndSources(), 1326 content::NotificationService::AllBrowserContextsAndSources(),
1323 content::NotificationService::NoDetails()); 1327 content::NotificationService::NoDetails());
1324 1328
1325 if (destroyed) 1329 if (destroyed)
1326 return; 1330 return;
1327 destroyed_ = NULL; 1331 destroyed_ = NULL;
1328 // Under chromeos we immediately set the |move_loop_widget_| to NULL. 1332 // Under chromeos we immediately set the |move_loop_widget_| to NULL.
1329 if (move_loop_widget_) { 1333 if (move_loop_widget_) {
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 drag_data_[i].source_model_index) { 1911 drag_data_[i].source_model_index) {
1908 return false; 1912 return false;
1909 } 1913 }
1910 } 1914 }
1911 return true; 1915 return true;
1912 } 1916 }
1913 1917
1914 Browser* TabDragController::CreateBrowserForDrag( 1918 Browser* TabDragController::CreateBrowserForDrag(
1915 TabStrip* source, 1919 TabStrip* source,
1916 const gfx::Point& point_in_screen, 1920 const gfx::Point& point_in_screen,
1921 gfx::Point* drag_offset,
1917 std::vector<gfx::Rect>* drag_bounds) { 1922 std::vector<gfx::Rect>* drag_bounds) {
1918 Browser* browser = new Browser( 1923 Browser* browser = new Browser(
1919 Browser::CreateParams(drag_data_[0].contents->profile())); 1924 Browser::CreateParams(drag_data_[0].contents->profile()));
1920 gfx::Point center(0, source->height() / 2); 1925 gfx::Point center(0, source->height() / 2);
1921 views::View::ConvertPointToWidget(source, &center); 1926 views::View::ConvertPointToWidget(source, &center);
1922 gfx::Rect new_bounds(source->GetWidget()->GetWindowBoundsInScreen()); 1927 gfx::Rect new_bounds(source->GetWidget()->GetWindowBoundsInScreen());
1923 new_bounds.set_y(point_in_screen.y() - center.y()); 1928 new_bounds.set_y(point_in_screen.y() - center.y());
1924 switch (GetDetachPosition(point_in_screen)) { 1929 switch (GetDetachPosition(point_in_screen)) {
1925 case DETACH_BEFORE: 1930 case DETACH_BEFORE:
1926 new_bounds.set_x(point_in_screen.x() - center.x()); 1931 new_bounds.set_x(point_in_screen.x() - center.x());
1927 new_bounds.Offset(-mouse_offset_.x(), 0); 1932 new_bounds.Offset(-mouse_offset_.x(), 0);
1928 break; 1933 break;
1929 1934
1930 case DETACH_AFTER: { 1935 case DETACH_AFTER: {
1931 gfx::Point right_edge(source->width(), 0); 1936 gfx::Point right_edge(source->width(), 0);
1932 views::View::ConvertPointToWidget(source, &right_edge); 1937 views::View::ConvertPointToWidget(source, &right_edge);
1933 new_bounds.set_x(point_in_screen.x() - right_edge.x()); 1938 new_bounds.set_x(point_in_screen.x() - right_edge.x());
1934 new_bounds.Offset(drag_bounds->back().right() - mouse_offset_.x(), 0); 1939 new_bounds.Offset(drag_bounds->back().right() - mouse_offset_.x(), 0);
1935 int delta = (*drag_bounds)[0].x(); 1940 int delta = (*drag_bounds)[0].x();
1936 for (size_t i = 0; i < drag_bounds->size(); ++i) 1941 for (size_t i = 0; i < drag_bounds->size(); ++i)
1937 (*drag_bounds)[i].Offset(-delta, 0); 1942 (*drag_bounds)[i].Offset(-delta, 0);
1938 break; 1943 break;
1939 } 1944 }
1940 1945
1941 default: 1946 default:
1942 break; // Nothing to do for DETACH_ABOVE_OR_BELOW. 1947 break; // Nothing to do for DETACH_ABOVE_OR_BELOW.
1943 } 1948 }
1944 1949
1950 *drag_offset = point_in_screen.Subtract(new_bounds.origin());
1951
1945 SetTrackedByWorkspace(browser->window()->GetNativeWindow(), false); 1952 SetTrackedByWorkspace(browser->window()->GetNativeWindow(), false);
1946 browser->window()->SetBounds(new_bounds); 1953 browser->window()->SetBounds(new_bounds);
1947 return browser; 1954 return browser;
1948 } 1955 }
1949 1956
1950 gfx::Point TabDragController::GetCursorScreenPoint() { 1957 gfx::Point TabDragController::GetCursorScreenPoint() {
1951 #if defined(USE_ASH) 1958 #if defined(USE_ASH)
1952 views::Widget* widget = GetAttachedBrowserWidget(); 1959 views::Widget* widget = GetAttachedBrowserWidget();
1953 DCHECK(widget); 1960 DCHECK(widget);
1954 if (aura::Env::GetInstance()->is_touch_down()) { 1961 if (aura::Env::GetInstance()->is_touch_down()) {
1955 aura::Window* widget_window = widget->GetNativeWindow(); 1962 aura::Window* widget_window = widget->GetNativeWindow();
1956 DCHECK(widget_window->GetRootWindow()); 1963 DCHECK(widget_window->GetRootWindow());
1957 gfx::Point touch_point; 1964 gfx::Point touch_point;
1958 bool got_touch_point = widget_window->GetRootWindow()-> 1965 bool got_touch_point = widget_window->GetRootWindow()->
1959 gesture_recognizer()->GetLastTouchPointForTarget(widget_window, 1966 gesture_recognizer()->GetLastTouchPointForTarget(widget_window,
1960 &touch_point); 1967 &touch_point);
1961 DCHECK(got_touch_point); 1968 DCHECK(got_touch_point);
1962 return touch_point; 1969 return touch_point;
1963 } 1970 }
1964 #endif 1971 #endif
1965 return gfx::Screen::GetCursorScreenPoint(); 1972 return gfx::Screen::GetCursorScreenPoint();
1966 } 1973 }
1974
1975 gfx::Point TabDragController::GetWindowOffset(
1976 const gfx::Point& point_in_screen) {
1977 TabStrip* owning_tabstrip = (attached_tabstrip_ && detach_into_browser_) ?
1978 attached_tabstrip_ : source_tabstrip_;
1979 views::View* toplevel_view = owning_tabstrip->GetWidget()->GetContentsView();
1980
1981 gfx::Point offset = point_in_screen;
1982 views::View::ConvertPointFromScreen(toplevel_view, &offset);
1983 return offset;
1984 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/tabs/tab_drag_controller.h ('k') | ui/aura/client/window_move_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698