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

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

Powered by Google App Engine
This is Rietveld 408576698