diff options
author | varkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-30 01:05:40 +0000 |
---|---|---|
committer | varkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-30 01:05:40 +0000 |
commit | 47491adcc933301b33e7f8605f1b0ba6ba31aafb (patch) | |
tree | a011b4fcf2e86502df17bcf098d1cc323178b8cd | |
parent | 8c79e3f62dacd2753a596b10264f941185644a5e (diff) | |
download | chromium_src-47491adcc933301b33e7f8605f1b0ba6ba31aafb.zip chromium_src-47491adcc933301b33e7f8605f1b0ba6ba31aafb.tar.gz chromium_src-47491adcc933301b33e7f8605f1b0ba6ba31aafb.tar.bz2 |
Not moving a docked window when restoring a previously maximized window. When a maximized window gets docked (possible with a secondary monitor - see bug steps to repro) it now gets restored first. This prevents weird animated behavior or hiding it when it gets undocked or restored.
Additionally a tab dragged out of a maximized browser and docked is not maximized anymore at the end of the drag (this used to be causing it to get undocked immediately).
BUG=309954
BUG=305276
TEST=interactive_ui_tests --gtest_filter=*TabDragControllerTest*DetachToDockedWindowFromMaximizedWindow*
Review URL: https://codereview.chromium.org/38073004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231698 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/wm/dock/docked_window_layout_manager.cc | 2 | ||||
-rw-r--r-- | ash/wm/panels/panel_frame_view.cc | 8 | ||||
-rw-r--r-- | ash/wm/window_state.cc | 5 | ||||
-rw-r--r-- | ash/wm/window_state.h | 1 | ||||
-rw-r--r-- | chrome/browser/ui/views/tabs/tab_drag_controller.cc | 25 | ||||
-rw-r--r-- | chrome/browser/ui/views/tabs/tab_drag_controller.h | 2 | ||||
-rw-r--r-- | chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc | 118 | ||||
-rw-r--r-- | ui/views/widget/root_view.cc | 1 |
8 files changed, 153 insertions, 9 deletions
diff --git a/ash/wm/dock/docked_window_layout_manager.cc b/ash/wm/dock/docked_window_layout_manager.cc index 8b64ffb..19f92f1 100644 --- a/ash/wm/dock/docked_window_layout_manager.cc +++ b/ash/wm/dock/docked_window_layout_manager.cc @@ -577,7 +577,7 @@ void DockedWindowLayoutManager::OnWindowShowTypeChanged( // Reparenting changes the source bounds for the animation if a window is // visible so hide it here and show later when it is already in the desktop. UndockWindow(window); - } else { + } else if (old_type == wm::SHOW_TYPE_MINIMIZED) { RestoreDockedWindow(window_state); } } diff --git a/ash/wm/panels/panel_frame_view.cc b/ash/wm/panels/panel_frame_view.cc index 0a6bce5..bafe29f 100644 --- a/ash/wm/panels/panel_frame_view.cc +++ b/ash/wm/panels/panel_frame_view.cc @@ -80,6 +80,10 @@ void PanelFrameView::Layout() { header_painter_->set_header_height(NonClientTopBorderHeight()); } +void PanelFrameView::GetWindowMask(const gfx::Size&, gfx::Path*) { + // Nothing. +} + void PanelFrameView::ResetWindowControls() { NOTIMPLEMENTED(); } @@ -99,10 +103,6 @@ void PanelFrameView::UpdateWindowTitle() { header_painter_->SchedulePaintForTitle(title_font_); } -void PanelFrameView::GetWindowMask(const gfx::Size&, gfx::Path*) { - // Nothing. -} - int PanelFrameView::NonClientHitTest(const gfx::Point& point) { if (!header_painter_) return HTNOWHERE; diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index d037a76..c441524 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc @@ -75,6 +75,11 @@ bool WindowState::IsActive() const { return IsActiveWindow(window_); } +bool WindowState::IsDocked() const { + return window_->parent() && + window_->parent()->id() == internal::kShellWindowId_DockedContainer; +} + bool WindowState::CanMaximize() const { return window_->GetProperty(aura::client::kCanMaximizeKey); } diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h index 653071f..560a91f 100644 --- a/ash/wm/window_state.h +++ b/ash/wm/window_state.h @@ -65,6 +65,7 @@ class ASH_EXPORT WindowState : public aura::WindowObserver { // SHOW_STATE_DEFAULT. bool IsNormalShowState() const; bool IsActive() const; + bool IsDocked() const; // Checks if the window can change its state accordingly. bool CanMaximize() const; diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index 8462a63..fc67b7f 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc @@ -209,6 +209,16 @@ void SetWindowPositionManaged(gfx::NativeWindow window, bool value) { #endif } +// Returns true if |tab_strip| browser window is docked. +bool IsDocked(const TabStrip* tab_strip) { +#if defined(USE_ASH) + DCHECK(tab_strip); + return ash::wm::GetWindowState( + tab_strip->GetWidget()->GetNativeWindow())->IsDocked(); +#endif + return false; +} + // Returns true if |bounds| contains the y-coordinate |y|. The y-coordinate // of |bounds| is adjusted by |vertical_adjustment|. bool DoesRectContainVerticalPointExpanded( @@ -484,7 +494,7 @@ void TabDragController::Init( } // static -bool TabDragController::IsAttachedTo(TabStrip* tab_strip) { +bool TabDragController::IsAttachedTo(const TabStrip* tab_strip) { return (instance_ && instance_->active() && instance_->attached_tabstrip() == tab_strip); } @@ -1873,6 +1883,11 @@ void TabDragController::CompleteDrag() { if (attached_tabstrip_) { if (is_dragging_new_browser_) { + if (IsDocked(attached_tabstrip_)) { + DCHECK_EQ(host_desktop_type_, chrome::HOST_DESKTOP_TYPE_ASH); + was_source_maximized_ = false; + was_source_fullscreen_ = false; + } // If source window was maximized - maximize the new window as well. if (was_source_maximized_) attached_tabstrip_->GetWidget()->Maximize(); @@ -1884,6 +1899,14 @@ void TabDragController::CompleteDrag() { ash::Shell::GetInstance()->delegate()->ToggleFullscreen(); } #endif + } else { + // When dragging results in maximized or fullscreen browser window getting + // docked, restore it. + if ((was_source_fullscreen_ || was_source_maximized_) && + (IsDocked(attached_tabstrip_))) { + DCHECK_EQ(host_desktop_type_, chrome::HOST_DESKTOP_TYPE_ASH); + attached_tabstrip_->GetWidget()->Restore(); + } } attached_tabstrip_->StoppedDraggingTabs( GetTabsMatchingDraggedContents(attached_tabstrip_), diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.h b/chrome/browser/ui/views/tabs/tab_drag_controller.h index dd86233..67ad0d9 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.h +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.h @@ -109,7 +109,7 @@ class TabDragController : public content::WebContentsDelegate, // |tab_strip|. // NOTE: this returns false if the TabDragController is in the process of // finishing the drag. - static bool IsAttachedTo(TabStrip* tab_strip); + static bool IsAttachedTo(const TabStrip* tab_strip); // Returns true if there is a drag underway. static bool IsActive(); diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index f8b89b0..0fbd5fc 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc @@ -48,6 +48,7 @@ #include "ash/shell.h" #include "ash/test/cursor_manager_test_api.h" #include "ash/wm/coordinate_conversion.h" +#include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" #include "ui/aura/client/screen_position_client.h" @@ -680,7 +681,7 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, EXPECT_TRUE(GetTrackedByWorkspace(browser())); EXPECT_TRUE(GetTrackedByWorkspace(new_browser)); - // After this both windows should still be managable. + // After this both windows should still be manageable. EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow())); EXPECT_TRUE(IsWindowPositionManaged( new_browser->window()->GetNativeWindow())); @@ -738,7 +739,7 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, EXPECT_TRUE(GetTrackedByWorkspace(browser())); EXPECT_TRUE(GetTrackedByWorkspace(new_browser)); - // After this both windows should still be managable. + // After this both windows should still be manageable. EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow())); EXPECT_TRUE(IsWindowPositionManaged( new_browser->window()->GetNativeWindow())); @@ -1320,6 +1321,7 @@ class DetachToBrowserInSeparateDisplayTabDragControllerTest : public DetachToBrowserTabDragControllerTest { public: DetachToBrowserInSeparateDisplayTabDragControllerTest() {} + virtual ~DetachToBrowserInSeparateDisplayTabDragControllerTest() {} virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { DetachToBrowserTabDragControllerTest::SetUpCommandLine(command_line); @@ -1339,6 +1341,7 @@ class DetachToBrowserTabDragControllerTestTouch : public DetachToBrowserTabDragControllerTest { public: DetachToBrowserTabDragControllerTestTouch() {} + virtual ~DetachToBrowserTabDragControllerTestTouch() {} private: DISALLOW_COPY_AND_ASSIGN(DetachToBrowserTabDragControllerTestTouch); @@ -1689,10 +1692,13 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest, } #endif // OS_CHROMEOS +// Subclass of DetachToBrowserTabDragControllerTest that +// creates multiple displays with different device scale factors. class DifferentDeviceScaleFactorDisplayTabDragControllerTest : public DetachToBrowserTabDragControllerTest { public: DifferentDeviceScaleFactorDisplayTabDragControllerTest() {} + virtual ~DifferentDeviceScaleFactorDisplayTabDragControllerTest() {} virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { DetachToBrowserTabDragControllerTest::SetUpCommandLine(command_line); @@ -2034,6 +2040,111 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestTouch, new_browser->window()->GetNativeWindow()->bounds().ToString()); } +// Subclass of DetachToBrowserTabDragControllerTest that runs tests with +// docked windows enabled and disabled. +class DetachToDockedTabDragControllerTest + : public DetachToBrowserTabDragControllerTest { + public: + DetachToDockedTabDragControllerTest() {} + virtual ~DetachToDockedTabDragControllerTest() {} + + private: + DISALLOW_COPY_AND_ASSIGN(DetachToDockedTabDragControllerTest); +}; + +namespace { + +void DetachToDockedWindowNextStep( + DetachToDockedTabDragControllerTest* test, + const gfx::Point& target_point, + int iteration) { + ASSERT_EQ(2u, test->native_browser_list->size()); + Browser* new_browser = test->native_browser_list->get(1); + ASSERT_TRUE(new_browser->window()->IsActive()); + + if (!iteration) { + ASSERT_TRUE(test->ReleaseInput()); + return; + } + ASSERT_TRUE(test->DragInputToNotifyWhenDone( + target_point.x(), target_point.y(), + base::Bind(&DetachToDockedWindowNextStep, + test, + gfx::Point(target_point.x(), 1 + target_point.y()), + iteration - 1))); +} + +} // namespace + +// Drags from browser to separate window, docks that window and releases mouse. +IN_PROC_BROWSER_TEST_P(DetachToDockedTabDragControllerTest, + DetachToDockedWindowFromMaximizedWindow) { + if (!TabDragController::ShouldDetachIntoNewBrowser()) { + VLOG(1) + << "Skipping DetachToDockedWindowFromMaximizedWindow on this platform."; + return; + } + + // Maximize the initial browser window. + browser()->window()->Maximize(); + ASSERT_TRUE(browser()->window()->IsMaximized()); + + // Add another tab. + AddTabAndResetBrowser(browser()); + TabStrip* tab_strip = GetTabStripForBrowser(browser()); + + // Move to the first tab and drag it enough so that it detaches. + gfx::Point tab_0_center( + GetCenterInScreenCoordinates(tab_strip->tab_at(0))); + ASSERT_TRUE(PressInput(tab_0_center)); + + // The following matches kMovesBeforeAdjust in snap_sizer.cc + const int kNumIterations = 25 * 5 + 10; + ASSERT_TRUE(DragInputToNotifyWhenDone( + tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), + base::Bind(&DetachToDockedWindowNextStep, this, + gfx::Point(0, tab_0_center.y() + GetDetachY(tab_strip)), + kNumIterations))); + // Continue dragging enough times to go through snapping sequence and dock + // the window. + QuitWhenNotDragging(); + // Should no longer be dragging. + ASSERT_FALSE(tab_strip->IsDragSessionActive()); + ASSERT_FALSE(TabDragController::IsActive()); + + // There should now be another browser. + ASSERT_EQ(2u, native_browser_list->size()); + Browser* new_browser = native_browser_list->get(1); + ASSERT_TRUE(new_browser->window()->IsActive()); + TabStrip* tab_strip2 = GetTabStripForBrowser(new_browser); + ASSERT_FALSE(tab_strip2->IsDragSessionActive()); + + EXPECT_EQ("0", IDString(new_browser->tab_strip_model())); + EXPECT_EQ("1", IDString(browser()->tab_strip_model())); + + // The bounds of the initial window should not have changed. + EXPECT_TRUE(browser()->window()->IsMaximized()); + + EXPECT_TRUE(GetTrackedByWorkspace(browser())); + EXPECT_TRUE(GetTrackedByWorkspace(new_browser)); + // After this both windows should still be manageable. + EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow())); + EXPECT_TRUE(IsWindowPositionManaged( + new_browser->window()->GetNativeWindow())); + + // The new window should be docked and not maximized if docking is allowed. + ash::wm::WindowState* window_state = + ash::wm::GetWindowState(new_browser->window()->GetNativeWindow()); + if (docked_windows_enabled()) { + EXPECT_FALSE(new_browser->window()->IsMaximized()); + EXPECT_TRUE(window_state->IsDocked()); + } else { + EXPECT_TRUE(new_browser->window()->IsMaximized()); + EXPECT_FALSE(window_state->IsDocked()); + } +} + + #endif #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash) @@ -2047,6 +2158,9 @@ INSTANTIATE_TEST_CASE_P(TabDragging, DetachToBrowserTabDragControllerTest, ::testing::Values("mouse", "touch")); INSTANTIATE_TEST_CASE_P(TabDragging, + DetachToDockedTabDragControllerTest, + ::testing::Values("mouse", "mouse docked")); +INSTANTIATE_TEST_CASE_P(TabDragging, DetachToBrowserTabDragControllerTestTouch, ::testing::Values("touch", "touch docked")); #else diff --git a/ui/views/widget/root_view.cc b/ui/views/widget/root_view.cc index e29ced9..95f94dc 100644 --- a/ui/views/widget/root_view.cc +++ b/ui/views/widget/root_view.cc @@ -639,6 +639,7 @@ void RootView::VisibilityChanged(View* /*starting_from*/, bool is_visible) { // When the root view is being hidden (e.g. when widget is minimized) // handlers are reset, so that after it is reshown, events are not captured // by old handlers. + explicit_mouse_handler_ = false; mouse_pressed_handler_ = NULL; mouse_move_handler_ = NULL; touch_pressed_handler_ = NULL; |