Commit e256bccf authored by Su Hong Koo's avatar Su Hong Koo Committed by Commit Bot

Support primary display swapping for >2 displays

Primary display swapping using Alt + F4 only recognized two displays.
Fixed by returning secondary display that is next to the primary display
in active_display_list_.

Bug: 867966
Change-Id: Icd395582bf48123c0a463e663b0db62c51e352d6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2019474Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Reviewed-by: default avatarBailey Berro <baileyberro@chromium.org>
Commit-Queue: Su Hong Koo <sukoo@google.com>
Cr-Commit-Position: refs/heads/master@{#738290}
parent be74f2df
......@@ -4,6 +4,7 @@
#include "ash/accelerators/accelerator_commands.h"
#include "ash/display/display_configuration_controller.h"
#include "ash/shell.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/screen_pinning_controller.h"
......@@ -97,5 +98,35 @@ void UnpinWindow() {
WindowState::Get(pinned_window)->Restore();
}
void ShiftPrimaryDisplay() {
display::DisplayManager* display_manager = Shell::Get()->display_manager();
CHECK_GE(display_manager->GetNumDisplays(), 2U);
const int64_t primary_display_id =
display::Screen::GetScreen()->GetPrimaryDisplay().id();
const display::Displays& active_display_list =
display_manager->active_display_list();
auto primary_display_iter =
std::find_if(active_display_list.begin(), active_display_list.end(),
[id = primary_display_id](const display::Display& display) {
return display.id() == id;
});
DCHECK(primary_display_iter != active_display_list.end());
++primary_display_iter;
// If we've reach the end of |active_display_list|, wrap back around to the
// front.
if (primary_display_iter == active_display_list.end())
primary_display_iter = active_display_list.begin();
Shell::Get()->display_configuration_controller()->SetPrimaryDisplayId(
primary_display_iter->id(), true /* throttle */);
}
} // namespace accelerators
} // namespace ash
......@@ -38,6 +38,10 @@ ASH_EXPORT bool CanUnpinWindow();
// If a window is pinned (aka forced fullscreen), exit from pinned mode.
ASH_EXPORT void UnpinWindow();
// Change primary display to the secondary display next to current primary
// display
ASH_EXPORT void ShiftPrimaryDisplay();
} // namespace accelerators
} // namespace ash
......
......@@ -10,6 +10,9 @@
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "ui/aura/window.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/screen.h"
#include "ui/display/test/display_manager_test_api.h"
namespace ash {
namespace accelerators {
......@@ -82,5 +85,56 @@ TEST_F(AcceleratorCommandsTest, Unpin) {
EXPECT_FALSE(window_state1->IsPinned());
}
TEST_F(AcceleratorCommandsTest, CycleSwapPrimaryDisplay) {
display::test::DisplayManagerTestApi(display_manager())
.SetFirstDisplayAsInternalDisplay();
UpdateDisplay("800x600,800x600,800x600");
display::DisplayIdList id_list = display_manager()->GetCurrentDisplayIdList();
ShiftPrimaryDisplay();
int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
EXPECT_EQ(id_list[1], primary_id);
ShiftPrimaryDisplay();
primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
EXPECT_EQ(id_list[2], primary_id);
ShiftPrimaryDisplay();
primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
EXPECT_EQ(id_list[0], primary_id);
}
TEST_F(AcceleratorCommandsTest, CycleMixedMirrorModeSwapPrimaryDisplay) {
UpdateDisplay("300x400,400x500,500x600");
display::DisplayIdList id_list = display_manager()->GetCurrentDisplayIdList();
// Turn on mixed mirror mode. (Mirror from the first display to the second
// display)
display::DisplayIdList dst_ids;
dst_ids.emplace_back(id_list[1]);
base::Optional<display::MixedMirrorModeParams> mixed_params(
base::in_place, id_list[0], dst_ids);
display_manager()->SetMirrorMode(display::MirrorMode::kMixed, mixed_params);
EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
EXPECT_EQ(id_list[0], display_manager()->mirroring_source_id());
EXPECT_TRUE(display_manager()->mixed_mirror_mode_params());
EXPECT_EQ(2U, display_manager()->GetNumDisplays());
ShiftPrimaryDisplay();
int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
EXPECT_EQ(id_list[2], primary_id);
ShiftPrimaryDisplay();
primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
EXPECT_EQ(id_list[0], primary_id);
ShiftPrimaryDisplay();
primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
EXPECT_EQ(id_list[2], primary_id);
}
} // namespace accelerators
} // namespace ash
......@@ -733,13 +733,7 @@ void HandleShowTaskManager() {
void HandleSwapPrimaryDisplay() {
base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
// TODO(rjkroege): This is not correct behaviour on devices with more than
// two screens. Behave the same as mirroring: fail and notify if there are
// three or more screens.
Shell::Get()->display_configuration_controller()->SetPrimaryDisplayId(
Shell::Get()->display_manager()->GetSecondaryDisplay().id(),
true /* throttle */);
accelerators::ShiftPrimaryDisplay();
}
bool CanHandleSwitchIme(const ui::Accelerator& accelerator) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment