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

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

Issue 80323002: Restores maximized browser before dragging a tab (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Restores maximized browser before dragging a tab (ash only) Created 7 years 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
« no previous file with comments | « chrome/browser/ui/views/tabs/tab_drag_controller.h ('k') | no next file » | 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/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 #endif 203 #endif
204 } 204 }
205 205
206 void SetWindowPositionManaged(gfx::NativeWindow window, bool value) { 206 void SetWindowPositionManaged(gfx::NativeWindow window, bool value) {
207 #if defined(USE_ASH) 207 #if defined(USE_ASH)
208 ash::wm::GetWindowState(window)->set_window_position_managed(value); 208 ash::wm::GetWindowState(window)->set_window_position_managed(value);
209 #endif 209 #endif
210 } 210 }
211 211
212 // Returns true if |tab_strip| browser window is docked. 212 // Returns true if |tab_strip| browser window is docked.
213 bool IsDocked(const TabStrip* tab_strip) { 213 bool IsDockedOrSnapped(const TabStrip* tab_strip) {
214 #if defined(USE_ASH) 214 #if defined(USE_ASH)
215 DCHECK(tab_strip); 215 DCHECK(tab_strip);
216 return ash::wm::GetWindowState( 216 ash::wm::WindowState* window_state =
217 tab_strip->GetWidget()->GetNativeWindow())->IsDocked(); 217 ash::wm::GetWindowState(tab_strip->GetWidget()->GetNativeWindow());
218 return window_state->IsDocked() ||
219 window_state->window_show_type() == ash::wm::SHOW_TYPE_LEFT_SNAPPED ||
220 window_state->window_show_type() == ash::wm::SHOW_TYPE_RIGHT_SNAPPED;
218 #endif 221 #endif
219 return false; 222 return false;
220 } 223 }
221 224
222 // Returns true if |bounds| contains the y-coordinate |y|. The y-coordinate 225 // Returns true if |bounds| contains the y-coordinate |y|. The y-coordinate
223 // of |bounds| is adjusted by |vertical_adjustment|. 226 // of |bounds| is adjusted by |vertical_adjustment|.
224 bool DoesRectContainVerticalPointExpanded( 227 bool DoesRectContainVerticalPointExpanded(
225 const gfx::Rect& bounds, 228 const gfx::Rect& bounds,
226 int vertical_adjustment, 229 int vertical_adjustment,
227 int y) { 230 int y) {
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 { 542 {
540 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); 543 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr());
541 SaveFocus(); 544 SaveFocus();
542 if (!ref) 545 if (!ref)
543 return; 546 return;
544 } 547 }
545 started_drag_ = true; 548 started_drag_ = true;
546 Attach(source_tabstrip_, gfx::Point()); 549 Attach(source_tabstrip_, gfx::Point());
547 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) == 550 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) ==
548 GetModel(source_tabstrip_)->count()) { 551 GetModel(source_tabstrip_)->count()) {
552 #if defined(USE_ASH)
553 if (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH &&
varkha 2013/11/27 19:54:45 This behavior is now ash-only - including ash on W
554 (was_source_maximized_ || was_source_fullscreen_)) {
555 // When all tabs in a maximized browser are dragged the browser gets
556 // restored during the drag and maximized back when the drag ends.
557 views::Widget* widget = GetAttachedBrowserWidget();
558 const int last_tabstrip_width = attached_tabstrip_->tab_area_width();
559 std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs();
560 OffsetX(GetAttachedDragPoint(point_in_screen).x(), &drag_bounds);
561 gfx::Rect new_bounds(CalculateDraggedBrowserBounds(source_tabstrip_,
562 point_in_screen,
563 &drag_bounds));
564 new_bounds.Offset(-widget->GetRestoredBounds().x() +
565 point_in_screen.x() -
566 mouse_offset_.x(), 0);
567 widget->SetVisibilityChangedAnimationsEnabled(false);
568 widget->Restore();
569 widget->SetBounds(new_bounds);
570 AdjustBrowserAndTabBoundsForDrag(last_tabstrip_width,
571 point_in_screen,
572 &drag_bounds);
573 widget->SetVisibilityChangedAnimationsEnabled(true);
574 }
575 #endif
549 RunMoveLoop(GetWindowOffset(point_in_screen)); 576 RunMoveLoop(GetWindowOffset(point_in_screen));
550 return; 577 return;
551 } 578 }
552 } 579 }
553 580
554 ContinueDragging(point_in_screen); 581 ContinueDragging(point_in_screen);
555 } 582 }
556 583
557 void TabDragController::EndDrag(EndDragReason reason) { 584 void TabDragController::EndDrag(EndDragReason reason) {
558 TRACE_EVENT0("views", "TabDragController::EndDrag"); 585 TRACE_EVENT0("views", "TabDragController::EndDrag");
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 // gesture sequence and the GR's touch events queue to the new window. This 1496 // gesture sequence and the GR's touch events queue to the new window. This
1470 // should really be done somewhere in capture change code and or inside the 1497 // should really be done somewhere in capture change code and or inside the
1471 // GR. But we currently do not have a consistent way for doing it that would 1498 // GR. But we currently do not have a consistent way for doing it that would
1472 // work in all cases. Hence this hack. 1499 // work in all cases. Hence this hack.
1473 ui::GestureRecognizer::Get()->TransferEventsTo( 1500 ui::GestureRecognizer::Get()->TransferEventsTo(
1474 attached_native_view, 1501 attached_native_view,
1475 dragged_widget->GetNativeView()); 1502 dragged_widget->GetNativeView());
1476 #endif 1503 #endif
1477 dragged_widget->SetVisibilityChangedAnimationsEnabled(false); 1504 dragged_widget->SetVisibilityChangedAnimationsEnabled(false);
1478 Attach(dragged_browser_view->tabstrip(), gfx::Point()); 1505 Attach(dragged_browser_view->tabstrip(), gfx::Point());
1479 attached_tabstrip_->InvalidateLayout(); 1506 AdjustBrowserAndTabBoundsForDrag(last_tabstrip_width,
1480 dragged_widget->non_client_view()->Layout(); 1507 point_in_screen,
1481 const int dragged_tabstrip_width = attached_tabstrip_->tab_area_width(); 1508 &drag_bounds);
1482
1483 // If the new tabstrip is smaller than the old resize the tabs.
1484 if (dragged_tabstrip_width < last_tabstrip_width) {
1485 const float leading_ratio =
1486 drag_bounds.front().x() / static_cast<float>(last_tabstrip_width);
1487 drag_bounds = CalculateBoundsForDraggedTabs();
1488
1489 if (drag_bounds.back().right() < dragged_tabstrip_width) {
1490 const int delta_x =
1491 std::min(static_cast<int>(leading_ratio * dragged_tabstrip_width),
1492 dragged_tabstrip_width -
1493 (drag_bounds.back().right() -
1494 drag_bounds.front().x()));
1495 OffsetX(delta_x, &drag_bounds);
1496 }
1497
1498 // Reposition the restored window such that the tab that was dragged remains
1499 // under the mouse cursor.
1500 gfx::Point offset(
1501 static_cast<int>(drag_bounds[source_tab_index_].width() *
1502 offset_to_width_ratio_) +
1503 drag_bounds[source_tab_index_].x(), 0);
1504 views::View::ConvertPointToWidget(attached_tabstrip_, &offset);
1505 gfx::Rect new_bounds = browser->window()->GetBounds();
1506 new_bounds.set_x(point_in_screen.x() - offset.x());
1507 browser->window()->SetBounds(new_bounds);
1508 }
1509
1510 attached_tabstrip_->SetTabBoundsForDrag(drag_bounds);
1511
1512 WindowPositionManagedUpdater updater; 1509 WindowPositionManagedUpdater updater;
1513 dragged_widget->AddObserver(&updater); 1510 dragged_widget->AddObserver(&updater);
1514 browser->window()->Show(); 1511 browser->window()->Show();
1515 dragged_widget->RemoveObserver(&updater); 1512 dragged_widget->RemoveObserver(&updater);
1516 dragged_widget->SetVisibilityChangedAnimationsEnabled(true); 1513 dragged_widget->SetVisibilityChangedAnimationsEnabled(true);
1517 // Activate may trigger a focus loss, destroying us. 1514 // Activate may trigger a focus loss, destroying us.
1518 { 1515 {
1519 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); 1516 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr());
1520 browser->window()->Activate(); 1517 browser->window()->Activate();
1521 if (!ref) 1518 if (!ref)
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1927 GetModel(source_tabstrip_)->InsertWebContentsAt( 1924 GetModel(source_tabstrip_)->InsertWebContentsAt(
1928 data->source_model_index, data->contents, 1925 data->source_model_index, data->contents,
1929 (data->pinned ? TabStripModel::ADD_PINNED : 0)); 1926 (data->pinned ? TabStripModel::ADD_PINNED : 0));
1930 } 1927 }
1931 } 1928 }
1932 1929
1933 void TabDragController::CompleteDrag() { 1930 void TabDragController::CompleteDrag() {
1934 DCHECK(started_drag_); 1931 DCHECK(started_drag_);
1935 1932
1936 if (attached_tabstrip_) { 1933 if (attached_tabstrip_) {
1937 if (is_dragging_new_browser_) { 1934 if (IsDockedOrSnapped(attached_tabstrip_)) {
1938 if (IsDocked(attached_tabstrip_)) { 1935 DCHECK_EQ(host_desktop_type_, chrome::HOST_DESKTOP_TYPE_ASH);
1939 DCHECK_EQ(host_desktop_type_, chrome::HOST_DESKTOP_TYPE_ASH); 1936 was_source_maximized_ = false;
1940 was_source_maximized_ = false; 1937 was_source_fullscreen_ = false;
1941 was_source_fullscreen_ = false; 1938 }
1942 } 1939 // If source window was maximized - maximize the new window as well.
1943 // If source window was maximized - maximize the new window as well. 1940 if (was_source_maximized_ || was_source_fullscreen_)
1944 if (was_source_maximized_) 1941 GetAttachedBrowserWidget()->Maximize();
1945 attached_tabstrip_->GetWidget()->Maximize();
1946 #if defined(USE_ASH) 1942 #if defined(USE_ASH)
1947 if (was_source_fullscreen_ && 1943 if (was_source_fullscreen_ &&
1948 host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH) { 1944 host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH) {
1949 // In fullscreen mode it is only possible to get here if the source 1945 // In fullscreen mode it is only possible to get here if the source
1950 // was in "immersive fullscreen" mode, so toggle it back on. 1946 // was in "immersive fullscreen" mode, so toggle it back on.
1951 ash::accelerators::ToggleFullscreen(); 1947 ash::accelerators::ToggleFullscreen();
1952 } 1948 }
1953 #endif 1949 #endif
1954 } else {
1955 // When dragging results in maximized or fullscreen browser window getting
1956 // docked, restore it.
1957 if ((was_source_fullscreen_ || was_source_maximized_) &&
1958 (IsDocked(attached_tabstrip_))) {
1959 DCHECK_EQ(host_desktop_type_, chrome::HOST_DESKTOP_TYPE_ASH);
1960 attached_tabstrip_->GetWidget()->Restore();
1961 }
1962 }
1963 attached_tabstrip_->StoppedDraggingTabs( 1950 attached_tabstrip_->StoppedDraggingTabs(
1964 GetTabsMatchingDraggedContents(attached_tabstrip_), 1951 GetTabsMatchingDraggedContents(attached_tabstrip_),
1965 initial_tab_positions_, 1952 initial_tab_positions_,
1966 move_behavior_ == MOVE_VISIBILE_TABS, 1953 move_behavior_ == MOVE_VISIBILE_TABS,
1967 true); 1954 true);
1968 } else { 1955 } else {
1969 if (dock_info_.type() != DockInfo::NONE) { 1956 if (dock_info_.type() != DockInfo::NONE) {
1970 switch (dock_info_.type()) { 1957 switch (dock_info_.type()) {
1971 case DockInfo::LEFT_OF_WINDOW: 1958 case DockInfo::LEFT_OF_WINDOW:
1972 content::RecordAction(UserMetricsAction("DockingWindow_Left")); 1959 content::RecordAction(UserMetricsAction("DockingWindow_Left"));
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
2241 bool TabDragController::AreTabsConsecutive() { 2228 bool TabDragController::AreTabsConsecutive() {
2242 for (size_t i = 1; i < drag_data_.size(); ++i) { 2229 for (size_t i = 1; i < drag_data_.size(); ++i) {
2243 if (drag_data_[i - 1].source_model_index + 1 != 2230 if (drag_data_[i - 1].source_model_index + 1 !=
2244 drag_data_[i].source_model_index) { 2231 drag_data_[i].source_model_index) {
2245 return false; 2232 return false;
2246 } 2233 }
2247 } 2234 }
2248 return true; 2235 return true;
2249 } 2236 }
2250 2237
2251 Browser* TabDragController::CreateBrowserForDrag( 2238 gfx::Rect TabDragController::CalculateDraggedBrowserBounds(
2252 TabStrip* source, 2239 TabStrip* source,
2253 const gfx::Point& point_in_screen, 2240 const gfx::Point& point_in_screen,
2254 gfx::Vector2d* drag_offset,
2255 std::vector<gfx::Rect>* drag_bounds) { 2241 std::vector<gfx::Rect>* drag_bounds) {
2256 gfx::Point center(0, source->height() / 2); 2242 gfx::Point center(0, source->height() / 2);
2257 views::View::ConvertPointToWidget(source, &center); 2243 views::View::ConvertPointToWidget(source, &center);
2258 gfx::Rect new_bounds(source->GetWidget()->GetRestoredBounds()); 2244 gfx::Rect new_bounds(source->GetWidget()->GetRestoredBounds());
2259 if (source->GetWidget()->IsMaximized()) { 2245 if (source->GetWidget()->IsMaximized()) {
2260 // If the restore bounds is really small, we don't want to honor it 2246 // If the restore bounds is really small, we don't want to honor it
2261 // (dragging a really small window looks wrong), instead make sure the new 2247 // (dragging a really small window looks wrong), instead make sure the new
2262 // window is at least 50% the size of the old. 2248 // window is at least 50% the size of the old.
2263 const gfx::Size max_size( 2249 const gfx::Size max_size(
2264 source->GetWidget()->GetWindowBoundsInScreen().size()); 2250 source->GetWidget()->GetWindowBoundsInScreen().size());
2265 new_bounds.set_width( 2251 new_bounds.set_width(
2266 std::max(max_size.width() / 2, new_bounds.width())); 2252 std::max(max_size.width() / 2, new_bounds.width()));
2267 new_bounds.set_height( 2253 new_bounds.set_height(
2268 std::max(max_size.height() / 2, new_bounds.width())); 2254 std::max(max_size.height() / 2, new_bounds.height()));
varkha 2013/11/27 19:54:45 This looked like copy and paste bug. Am I correct
sky 2013/12/02 15:51:39 Ya, looks like a copy/paste error.
2269 } 2255 }
2270 new_bounds.set_y(point_in_screen.y() - center.y()); 2256 new_bounds.set_y(point_in_screen.y() - center.y());
2271 switch (GetDetachPosition(point_in_screen)) { 2257 switch (GetDetachPosition(point_in_screen)) {
2272 case DETACH_BEFORE: 2258 case DETACH_BEFORE:
2273 new_bounds.set_x(point_in_screen.x() - center.x()); 2259 new_bounds.set_x(point_in_screen.x() - center.x());
2274 new_bounds.Offset(-mouse_offset_.x(), 0); 2260 new_bounds.Offset(-mouse_offset_.x(), 0);
2275 break; 2261 break;
2276 case DETACH_AFTER: { 2262 case DETACH_AFTER: {
2277 gfx::Point right_edge(source->width(), 0); 2263 gfx::Point right_edge(source->width(), 0);
2278 views::View::ConvertPointToWidget(source, &right_edge); 2264 views::View::ConvertPointToWidget(source, &right_edge);
2279 new_bounds.set_x(point_in_screen.x() - right_edge.x()); 2265 new_bounds.set_x(point_in_screen.x() - right_edge.x());
2280 new_bounds.Offset(drag_bounds->back().right() - mouse_offset_.x(), 0); 2266 new_bounds.Offset(drag_bounds->back().right() - mouse_offset_.x(), 0);
2281 OffsetX(-(*drag_bounds)[0].x(), drag_bounds); 2267 OffsetX(-(*drag_bounds)[0].x(), drag_bounds);
2282 break; 2268 break;
2283 } 2269 }
2284 default: 2270 default:
2285 break; // Nothing to do for DETACH_ABOVE_OR_BELOW. 2271 break; // Nothing to do for DETACH_ABOVE_OR_BELOW.
2286 } 2272 }
2287 2273
2288 // To account for the extra vertical on restored windows that is absent on 2274 // To account for the extra vertical on restored windows that is absent on
2289 // maximized windows, add an additional vertical offset extracted from the tab 2275 // maximized windows, add an additional vertical offset extracted from the tab
2290 // strip. 2276 // strip.
2291 if (source->GetWidget()->IsMaximized()) 2277 if (source->GetWidget()->IsMaximized())
2292 new_bounds.Offset(0, -source->button_v_offset()); 2278 new_bounds.Offset(0, -source->button_v_offset());
2279 return new_bounds;
2280 }
2293 2281
2282 void TabDragController::AdjustBrowserAndTabBoundsForDrag(
2283 int last_tabstrip_width,
2284 const gfx::Point& point_in_screen,
2285 std::vector<gfx::Rect>* drag_bounds) {
2286 attached_tabstrip_->InvalidateLayout();
2287 attached_tabstrip_->DoLayout();
2288 const int dragged_tabstrip_width = attached_tabstrip_->tab_area_width();
2289
2290 // If the new tabstrip is smaller than the old resize the tabs.
2291 if (dragged_tabstrip_width < last_tabstrip_width) {
2292 const float leading_ratio =
2293 drag_bounds->front().x() / static_cast<float>(last_tabstrip_width);
2294 *drag_bounds = CalculateBoundsForDraggedTabs();
2295
2296 if (drag_bounds->back().right() < dragged_tabstrip_width) {
2297 const int delta_x =
2298 std::min(static_cast<int>(leading_ratio * dragged_tabstrip_width),
2299 dragged_tabstrip_width -
2300 (drag_bounds->back().right() -
2301 drag_bounds->front().x()));
2302 OffsetX(delta_x, drag_bounds);
2303 }
2304
2305 // Reposition the restored window such that the tab that was dragged remains
2306 // under the mouse cursor.
2307 gfx::Point offset(
2308 static_cast<int>((*drag_bounds)[source_tab_index_].width() *
2309 offset_to_width_ratio_) +
2310 (*drag_bounds)[source_tab_index_].x(), 0);
2311 views::View::ConvertPointToWidget(attached_tabstrip_, &offset);
2312 gfx::Rect bounds = GetAttachedBrowserWidget()->GetWindowBoundsInScreen();
2313 bounds.set_x(point_in_screen.x() - offset.x());
2314 GetAttachedBrowserWidget()->SetBounds(bounds);
2315 }
2316 attached_tabstrip_->SetTabBoundsForDrag(*drag_bounds);
2317 }
2318
2319 Browser* TabDragController::CreateBrowserForDrag(
2320 TabStrip* source,
2321 const gfx::Point& point_in_screen,
2322 gfx::Vector2d* drag_offset,
2323 std::vector<gfx::Rect>* drag_bounds) {
2324 gfx::Rect new_bounds(CalculateDraggedBrowserBounds(source,
2325 point_in_screen,
2326 drag_bounds));
2294 *drag_offset = point_in_screen - new_bounds.origin(); 2327 *drag_offset = point_in_screen - new_bounds.origin();
2295 2328
2296 Profile* profile = 2329 Profile* profile =
2297 Profile::FromBrowserContext(drag_data_[0].contents->GetBrowserContext()); 2330 Profile::FromBrowserContext(drag_data_[0].contents->GetBrowserContext());
2298 Browser::CreateParams create_params(Browser::TYPE_TABBED, 2331 Browser::CreateParams create_params(Browser::TYPE_TABBED,
2299 profile, 2332 profile,
2300 host_desktop_type_); 2333 host_desktop_type_);
2301 create_params.initial_bounds = new_bounds; 2334 create_params.initial_bounds = new_bounds;
2302 Browser* browser = new Browser(create_params); 2335 Browser* browser = new Browser(create_params);
2303 is_dragging_new_browser_ = true; 2336 is_dragging_new_browser_ = true;
(...skipping 29 matching lines...) Expand all
2333 gfx::Vector2d TabDragController::GetWindowOffset( 2366 gfx::Vector2d TabDragController::GetWindowOffset(
2334 const gfx::Point& point_in_screen) { 2367 const gfx::Point& point_in_screen) {
2335 TabStrip* owning_tabstrip = (attached_tabstrip_ && detach_into_browser_) ? 2368 TabStrip* owning_tabstrip = (attached_tabstrip_ && detach_into_browser_) ?
2336 attached_tabstrip_ : source_tabstrip_; 2369 attached_tabstrip_ : source_tabstrip_;
2337 views::View* toplevel_view = owning_tabstrip->GetWidget()->GetContentsView(); 2370 views::View* toplevel_view = owning_tabstrip->GetWidget()->GetContentsView();
2338 2371
2339 gfx::Point point = point_in_screen; 2372 gfx::Point point = point_in_screen;
2340 views::View::ConvertPointFromScreen(toplevel_view, &point); 2373 views::View::ConvertPointFromScreen(toplevel_view, &point);
2341 return point.OffsetFromOrigin(); 2374 return point.OffsetFromOrigin();
2342 } 2375 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/tabs/tab_drag_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698