summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvarkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-30 01:05:40 +0000
committervarkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-30 01:05:40 +0000
commit47491adcc933301b33e7f8605f1b0ba6ba31aafb (patch)
treea011b4fcf2e86502df17bcf098d1cc323178b8cd
parent8c79e3f62dacd2753a596b10264f941185644a5e (diff)
downloadchromium_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.cc2
-rw-r--r--ash/wm/panels/panel_frame_view.cc8
-rw-r--r--ash/wm/window_state.cc5
-rw-r--r--ash/wm/window_state.h1
-rw-r--r--chrome/browser/ui/views/tabs/tab_drag_controller.cc25
-rw-r--r--chrome/browser/ui/views/tabs/tab_drag_controller.h2
-rw-r--r--chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc118
-rw-r--r--ui/views/widget/root_view.cc1
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;