diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-13 09:35:38 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-13 09:35:38 +0000 |
commit | 098c299ffc1d2c4e6fe4158598651a18bc77283f (patch) | |
tree | 31d99c54e87d79fea5418fca9860f64dde322dec | |
parent | 5f7a16e738cb888e24bf355525226a308d6be47c (diff) | |
download | chromium_src-098c299ffc1d2c4e6fe4158598651a18bc77283f.zip chromium_src-098c299ffc1d2c4e6fe4158598651a18bc77283f.tar.gz chromium_src-098c299ffc1d2c4e6fe4158598651a18bc77283f.tar.bz2 |
Dont' update focus when moving mirror to docked mode
In this case, the root window is reassigned to another display, so no need to update the focus.
BUG=283173
TEST=covered by unit test
Review URL: https://codereview.chromium.org/70793002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234788 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/display/display_controller.cc | 10 | ||||
-rw-r--r-- | ash/display/display_controller.h | 2 | ||||
-rw-r--r-- | ash/display/display_controller_unittest.cc | 62 | ||||
-rw-r--r-- | ash/display/display_manager.cc | 8 | ||||
-rw-r--r-- | ash/display/display_manager.h | 4 |
5 files changed, 77 insertions, 9 deletions
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc index 579975a..2204ac2 100644 --- a/ash/display/display_controller.cc +++ b/ash/display/display_controller.cc @@ -143,7 +143,7 @@ class FocusActivationStore { active_(NULL) { } - void Store(bool display_removed) { + void Store(bool clear_focus) { if (!activation_client_) { aura::Window* root = Shell::GetPrimaryRootWindow(); activation_client_ = aura::client::GetActivationClient(root); @@ -158,7 +158,7 @@ class FocusActivationStore { tracker_.Add(active_); // Deactivate the window to close menu / bubble windows. - if (display_removed) + if (clear_focus) activation_client_->DeactivateWindow(active_); // Release capture if any. @@ -167,7 +167,7 @@ class FocusActivationStore { // window may be deleted when losing focus (fullscreen flash for // example). If the focused window is still alive after move, it'll // be re-focused below. - if (display_removed) + if (clear_focus) focus_client_->FocusWindow(NULL); } @@ -702,9 +702,9 @@ void DisplayController::CloseNonDesktopDisplay() { virtual_keyboard_window_controller_->Close(); } -void DisplayController::PreDisplayConfigurationChange(bool display_removed) { +void DisplayController::PreDisplayConfigurationChange(bool clear_focus) { FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); - focus_activation_store_->Store(display_removed); + focus_activation_store_->Store(clear_focus); gfx::Point point_in_screen = Shell::GetScreen()->GetCursorScreenPoint(); gfx::Display display = diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h index 005eebd..9dc20f5 100644 --- a/ash/display/display_controller.h +++ b/ash/display/display_controller.h @@ -163,7 +163,7 @@ class ASH_EXPORT DisplayController : public gfx::DisplayObserver, virtual void CreateOrUpdateNonDesktopDisplay( const internal::DisplayInfo& info) OVERRIDE; virtual void CloseNonDesktopDisplay() OVERRIDE; - virtual void PreDisplayConfigurationChange(bool dispay_removed) OVERRIDE; + virtual void PreDisplayConfigurationChange(bool clear_focus) OVERRIDE; virtual void PostDisplayConfigurationChange() OVERRIDE; private: diff --git a/ash/display/display_controller_unittest.cc b/ash/display/display_controller_unittest.cc index eff5755..b424aeb 100644 --- a/ash/display/display_controller_unittest.cc +++ b/ash/display/display_controller_unittest.cc @@ -15,6 +15,7 @@ #include "ash/test/ash_test_base.h" #include "ash/test/cursor_manager_test_api.h" #include "ash/test/display_manager_test_api.h" +#include "ash/wm/window_state.h" #include "base/command_line.h" #include "ui/aura/client/activation_change_observer.h" #include "ui/aura/client/activation_client.h" @@ -439,6 +440,66 @@ TEST_F(DisplayControllerTest, SecondaryDisplayLayout) { EXPECT_LE(1, observer.GetActivationChangedCountAndReset()); } +namespace { + +internal::DisplayInfo CreateDisplayInfo(int64 id, + const gfx::Rect& bounds, + float device_scale_factor) { + internal::DisplayInfo info(id, "", false); + info.SetBounds(bounds); + info.set_device_scale_factor(device_scale_factor); + return info; +} + +} // namespace + +TEST_F(DisplayControllerTest, MirrorToDockedWithFullscreen) { + // Creates windows to catch activation change event. + scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1)); + w1->Focus(); + + // Docked mode. + internal::DisplayManager* display_manager = + Shell::GetInstance()->display_manager(); + + const internal::DisplayInfo internal_display_info = + CreateDisplayInfo(1, gfx::Rect(0, 0, 500, 500), 2.0f); + const internal::DisplayInfo external_display_info = + CreateDisplayInfo(2, gfx::Rect(0, 0, 500, 500), 1.0f); + + std::vector<internal::DisplayInfo> display_info_list; + // Mirror. + display_info_list.push_back(internal_display_info); + display_info_list.push_back(external_display_info); + display_manager->OnNativeDisplaysChanged(display_info_list); + const int64 internal_display_id = + test::DisplayManagerTestApi(display_manager). + SetFirstDisplayAsInternalDisplay(); + EXPECT_EQ(1, internal_display_id); + EXPECT_EQ(2U, display_manager->num_connected_displays()); + EXPECT_EQ(1U, display_manager->GetNumDisplays()); + + wm::WindowState* window_state = wm::GetWindowState(w1.get()); + window_state->ToggleFullscreen(); + EXPECT_TRUE(window_state->IsFullscreen()); + EXPECT_EQ("0,0 250x250", w1->bounds().ToString()); + // Dock mode. + TestObserver observer; + display_info_list.clear(); + display_info_list.push_back(external_display_info); + display_manager->OnNativeDisplaysChanged(display_info_list); + EXPECT_EQ(1U, display_manager->GetNumDisplays()); + EXPECT_EQ(1U, display_manager->num_connected_displays()); + EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset()); + EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset()); + EXPECT_EQ(1, observer.CountAndReset()); + EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); + EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); + + EXPECT_TRUE(window_state->IsFullscreen()); + EXPECT_EQ("0,0 500x500", w1->bounds().ToString()); +} + TEST_F(DisplayControllerTest, BoundsUpdated) { if (!SupportsMultipleDisplays()) return; @@ -1180,7 +1241,6 @@ TEST_F(DisplayControllerTest, DockToSingle) { display_info_list.push_back(internal_display_info); display_info_list.push_back(external_display_info); display_manager->OnNativeDisplaysChanged(display_info_list); - EXPECT_EQ(2U, display_manager->GetNumDisplays()); const int64 internal_display_id = test::DisplayManagerTestApi(display_manager). SetFirstDisplayAsInternalDisplay(); diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc index a4c5f75..855221b 100644 --- a/ash/display/display_manager.cc +++ b/ash/display/display_manager.cc @@ -693,8 +693,14 @@ void DisplayManager::UpdateDisplays( removed_displays.empty()) { return; } + // Clear focus if the display has been removed, but don't clear focus if + // the destkop has been moved from one display to another + // (mirror -> docked, docked -> single internal). + bool clear_focus = + !removed_displays.empty() && + !(removed_displays.size() == 1 && added_display_indices.size() == 1); if (delegate_) - delegate_->PreDisplayConfigurationChange(!removed_displays.empty()); + delegate_->PreDisplayConfigurationChange(clear_focus); size_t updated_index; if (UpdateSecondaryDisplayBoundsForLayout(&new_displays, &updated_index) && diff --git a/ash/display/display_manager.h b/ash/display/display_manager.h index d79654b..4b53dac 100644 --- a/ash/display/display_manager.h +++ b/ash/display/display_manager.h @@ -59,7 +59,9 @@ class ASH_EXPORT DisplayManager virtual void CloseNonDesktopDisplay() = 0; // Called before and after the display configuration changes. - virtual void PreDisplayConfigurationChange(bool display_removed) = 0; + // When |clear_focus| is true, the implementation should + // deactivate the active window and set the focus window to NULL. + virtual void PreDisplayConfigurationChange(bool clear_focus) = 0; virtual void PostDisplayConfigurationChange() = 0; }; |