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

Side by Side Diff: ash/display/display_controller.cc

Issue 10870036: Allow storing display preferences per device. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 3 months 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 | Annotate | Revision Log
« no previous file with comments | « ash/display/display_controller.h ('k') | ash/display/display_controller_unittest.cc » ('j') | 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 "ash/display/display_controller.h" 5 #include "ash/display/display_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ash/ash_switches.h" 9 #include "ash/ash_switches.h"
10 #include "ash/display/multi_display_manager.h" 10 #include "ash/display/multi_display_manager.h"
11 #include "ash/root_window_controller.h" 11 #include "ash/root_window_controller.h"
12 #include "ash/screen_ash.h" 12 #include "ash/screen_ash.h"
13 #include "ash/shell.h" 13 #include "ash/shell.h"
14 #include "ash/wm/coordinate_conversion.h" 14 #include "ash/wm/coordinate_conversion.h"
15 #include "ash/wm/property_util.h" 15 #include "ash/wm/property_util.h"
16 #include "ash/wm/window_util.h" 16 #include "ash/wm/window_util.h"
17 #include "base/command_line.h" 17 #include "base/command_line.h"
18 #include "base/json/json_value_converter.h"
19 #include "base/string_piece.h"
20 #include "base/values.h"
18 #include "ui/aura/client/screen_position_client.h" 21 #include "ui/aura/client/screen_position_client.h"
19 #include "ui/aura/env.h" 22 #include "ui/aura/env.h"
20 #include "ui/aura/root_window.h" 23 #include "ui/aura/root_window.h"
21 #include "ui/aura/window.h" 24 #include "ui/aura/window.h"
22 #include "ui/compositor/dip_util.h" 25 #include "ui/compositor/dip_util.h"
23 #include "ui/gfx/display.h" 26 #include "ui/gfx/display.h"
24 #include "ui/gfx/screen.h" 27 #include "ui/gfx/screen.h"
25 28
26 #if defined(OS_CHROMEOS) 29 #if defined(OS_CHROMEOS)
27 #include "base/chromeos/chromeos_version.h" 30 #include "base/chromeos/chromeos_version.h"
28 #endif 31 #endif
29 32
30 namespace ash { 33 namespace ash {
31 namespace internal {
32 namespace { 34 namespace {
33 35
36 // The maximum value for 'offset' in DisplayLayout in case of outliers. Need
37 // to change this value in case to support even larger displays.
38 const int kMaxValidOffset = 10000;
39
34 // The number of pixels to overlap between the primary and secondary displays, 40 // The number of pixels to overlap between the primary and secondary displays,
35 // in case that the offset value is too large. 41 // in case that the offset value is too large.
36 const int kMinimumOverlapForInvalidOffset = 50; 42 const int kMinimumOverlapForInvalidOffset = 50;
37 43
44 bool GetPositionFromString(const base::StringPiece& position,
45 DisplayLayout::Position* field) {
46 if (position == "top") {
47 *field = DisplayLayout::TOP;
48 return true;
49 } else if (position == "bottom") {
50 *field = DisplayLayout::BOTTOM;
51 return true;
52 } else if (position == "right") {
53 *field = DisplayLayout::RIGHT;
54 return true;
55 } else if (position == "left") {
56 *field = DisplayLayout::LEFT;
57 return true;
58 }
59 LOG(ERROR) << "Invalid position value: " << position;
60
61 return false;
38 } 62 }
39 63
40 DisplayController::DisplayController() 64 } // namespace
41 : secondary_display_layout_(RIGHT), 65
42 secondary_display_offset_(0) { 66 DisplayLayout::DisplayLayout()
67 : position(RIGHT),
68 offset(0) {}
69
70 DisplayLayout::DisplayLayout(DisplayLayout::Position position, int offset)
71 : position(position),
72 offset(offset) {
73 DCHECK_LE(TOP, position);
74 DCHECK_GE(LEFT, position);
75
76 // Set the default value to |position| in case position is invalid. DCHECKs
77 // above doesn't stop in Release builds.
78 if (TOP > position || LEFT < position)
79 this->position = RIGHT;
80
81 DCHECK_GE(kMaxValidOffset, abs(offset));
82 }
83
84 // static
85 bool DisplayLayout::ConvertFromValue(const base::Value& value,
86 DisplayLayout* layout) {
87 base::JSONValueConverter<DisplayLayout> converter;
88 return converter.Convert(value, layout);
89 }
90
91 // static
92 bool DisplayLayout::ConvertToValue(const DisplayLayout& layout,
93 base::Value* value) {
94 base::DictionaryValue* dict_value = NULL;
95 if (!value->GetAsDictionary(&dict_value) || dict_value == NULL)
96 return false;
97
98 std::string position_value;
99 switch (layout.position) {
100 case TOP:
101 position_value = "top";
102 break;
103 case BOTTOM:
104 position_value = "bottom";
105 break;
106 case RIGHT:
107 position_value = "right";
108 break;
109 case LEFT:
110 position_value = "left";
111 break;
112 default:
113 return false;
114 }
115
116 dict_value->SetString("position", position_value);
117 dict_value->SetInteger("offset", layout.offset);
118 return true;
119 }
120
121 // static
122 void DisplayLayout::RegisterJSONConverter(
123 base::JSONValueConverter<DisplayLayout>* converter) {
124 converter->RegisterCustomField<Position>(
125 "position", &DisplayLayout::position, &GetPositionFromString);
126 converter->RegisterIntField("offset", &DisplayLayout::offset);
127 }
128
129 DisplayController::DisplayController() {
43 aura::Env::GetInstance()->display_manager()->AddObserver(this); 130 aura::Env::GetInstance()->display_manager()->AddObserver(this);
44 } 131 }
45 132
46 DisplayController::~DisplayController() { 133 DisplayController::~DisplayController() {
47 aura::Env::GetInstance()->display_manager()->RemoveObserver(this); 134 aura::Env::GetInstance()->display_manager()->RemoveObserver(this);
48 // Delete all root window controllers, which deletes root window 135 // Delete all root window controllers, which deletes root window
49 // from the last so that the primary root window gets deleted last. 136 // from the last so that the primary root window gets deleted last.
50 for (std::map<int64, aura::RootWindow*>::const_reverse_iterator it = 137 for (std::map<int64, aura::RootWindow*>::const_reverse_iterator it =
51 root_windows_.rbegin(); it != root_windows_.rend(); ++it) { 138 root_windows_.rbegin(); it != root_windows_.rend(); ++it) {
52 internal::RootWindowController* controller = 139 internal::RootWindowController* controller =
(...skipping 20 matching lines...) Expand all
73 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); 160 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root);
74 } 161 }
75 CommandLine* command_line = CommandLine::ForCurrentProcess(); 162 CommandLine* command_line = CommandLine::ForCurrentProcess();
76 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) { 163 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) {
77 std::string value = command_line->GetSwitchValueASCII( 164 std::string value = command_line->GetSwitchValueASCII(
78 switches::kAshSecondaryDisplayLayout); 165 switches::kAshSecondaryDisplayLayout);
79 char layout; 166 char layout;
80 int offset; 167 int offset;
81 if (sscanf(value.c_str(), "%c,%d", &layout, &offset) == 2) { 168 if (sscanf(value.c_str(), "%c,%d", &layout, &offset) == 2) {
82 if (layout == 't') 169 if (layout == 't')
83 secondary_display_layout_ = TOP; 170 default_display_layout_.position = DisplayLayout::TOP;
84 else if (layout == 'b') 171 else if (layout == 'b')
85 secondary_display_layout_ = BOTTOM; 172 default_display_layout_.position = DisplayLayout::BOTTOM;
86 else if (layout == 'r') 173 else if (layout == 'r')
87 secondary_display_layout_ = RIGHT; 174 default_display_layout_.position = DisplayLayout::RIGHT;
88 else if (layout == 'l') 175 else if (layout == 'l')
89 secondary_display_layout_ = LEFT; 176 default_display_layout_.position = DisplayLayout::LEFT;
90 secondary_display_offset_ = offset; 177 default_display_layout_.offset = offset;
91 } 178 }
92 } 179 }
93 UpdateDisplayBoundsForLayout(); 180 UpdateDisplayBoundsForLayout();
94 } 181 }
95 182
96 aura::RootWindow* DisplayController::GetPrimaryRootWindow() { 183 aura::RootWindow* DisplayController::GetPrimaryRootWindow() {
97 DCHECK(!root_windows_.empty()); 184 DCHECK(!root_windows_.empty());
98 aura::DisplayManager* display_manager = 185 aura::DisplayManager* display_manager =
99 aura::Env::GetInstance()->display_manager(); 186 aura::Env::GetInstance()->display_manager();
100 return root_windows_[display_manager->GetDisplayAt(0)->id()]; 187 return root_windows_[display_manager->GetDisplayAt(0)->id()];
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 for (std::map<int64, aura::RootWindow*>::const_iterator it = 225 for (std::map<int64, aura::RootWindow*>::const_iterator it =
139 root_windows_.begin(); it != root_windows_.end(); ++it) { 226 root_windows_.begin(); it != root_windows_.end(); ++it) {
140 internal::RootWindowController* controller = 227 internal::RootWindowController* controller =
141 GetRootWindowController(it->second); 228 GetRootWindowController(it->second);
142 if (controller) 229 if (controller)
143 controllers.push_back(controller); 230 controllers.push_back(controller);
144 } 231 }
145 return controllers; 232 return controllers;
146 } 233 }
147 234
148 void DisplayController::SetSecondaryDisplayLayout( 235 void DisplayController::SetDefaultDisplayLayout(const DisplayLayout& layout) {
149 SecondaryDisplayLayout layout) { 236 default_display_layout_ = layout;
150 secondary_display_layout_ = layout;
151 UpdateDisplayBoundsForLayout(); 237 UpdateDisplayBoundsForLayout();
152 } 238 }
153 239
154 void DisplayController::SetSecondaryDisplayOffset(int offset) { 240 void DisplayController::SetLayoutForDisplayName(const std::string& name,
155 secondary_display_offset_ = offset; 241 const DisplayLayout& layout) {
242 secondary_layouts_[name] = layout;
156 UpdateDisplayBoundsForLayout(); 243 UpdateDisplayBoundsForLayout();
157 } 244 }
158 245
246 const DisplayLayout& DisplayController::GetLayoutForDisplayName(
247 const std::string& name) {
248 std::map<std::string, DisplayLayout>::const_iterator it =
249 secondary_layouts_.find(name);
250
251 if (it != secondary_layouts_.end())
252 return it->second;
253 return default_display_layout_;
254 }
159 255
160 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { 256 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) {
161 root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel()); 257 root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel());
162 UpdateDisplayBoundsForLayout(); 258 UpdateDisplayBoundsForLayout();
163 } 259 }
164 260
165 void DisplayController::OnDisplayAdded(const gfx::Display& display) { 261 void DisplayController::OnDisplayAdded(const gfx::Display& display) {
166 DCHECK(!root_windows_.empty()); 262 DCHECK(!root_windows_.empty());
167 aura::RootWindow* root = AddRootWindowForDisplay(display); 263 aura::RootWindow* root = AddRootWindowForDisplay(display);
168 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); 264 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 304
209 void DisplayController::UpdateDisplayBoundsForLayout() { 305 void DisplayController::UpdateDisplayBoundsForLayout() {
210 if (gfx::Screen::GetNumDisplays() <= 1) 306 if (gfx::Screen::GetNumDisplays() <= 1)
211 return; 307 return;
212 308
213 DCHECK_EQ(2, gfx::Screen::GetNumDisplays()); 309 DCHECK_EQ(2, gfx::Screen::GetNumDisplays());
214 aura::DisplayManager* display_manager = 310 aura::DisplayManager* display_manager =
215 aura::Env::GetInstance()->display_manager(); 311 aura::Env::GetInstance()->display_manager();
216 const gfx::Rect& primary_bounds = display_manager->GetDisplayAt(0)->bounds(); 312 const gfx::Rect& primary_bounds = display_manager->GetDisplayAt(0)->bounds();
217 gfx::Display* secondary_display = display_manager->GetDisplayAt(1); 313 gfx::Display* secondary_display = display_manager->GetDisplayAt(1);
314 const std::string& secondary_name = display_manager->GetDisplayNameAt(1);
218 const gfx::Rect& secondary_bounds = secondary_display->bounds(); 315 const gfx::Rect& secondary_bounds = secondary_display->bounds();
219 gfx::Point new_secondary_origin = primary_bounds.origin(); 316 gfx::Point new_secondary_origin = primary_bounds.origin();
220 317
318 const DisplayLayout* layout = &default_display_layout_;
319 std::map<std::string, DisplayLayout>::const_iterator iter =
320 secondary_layouts_.find(secondary_name);
321 if (iter != secondary_layouts_.end())
322 layout = &iter->second;
323
324 DisplayLayout::Position position = layout->position;
325
221 // Ignore the offset in case the secondary display doesn't share edges with 326 // Ignore the offset in case the secondary display doesn't share edges with
222 // the primary display. 327 // the primary display.
223 int offset = secondary_display_offset_; 328 int offset = layout->offset;
224 if (secondary_display_layout_ == TOP || secondary_display_layout_ == BOTTOM) { 329 if (position == DisplayLayout::TOP || position == DisplayLayout::BOTTOM) {
225 offset = std::min( 330 offset = std::min(
226 offset, primary_bounds.width() - kMinimumOverlapForInvalidOffset); 331 offset, primary_bounds.width() - kMinimumOverlapForInvalidOffset);
227 offset = std::max( 332 offset = std::max(
228 offset, -secondary_bounds.width() + kMinimumOverlapForInvalidOffset); 333 offset, -secondary_bounds.width() + kMinimumOverlapForInvalidOffset);
229 } else { 334 } else {
230 offset = std::min( 335 offset = std::min(
231 offset, primary_bounds.height() - kMinimumOverlapForInvalidOffset); 336 offset, primary_bounds.height() - kMinimumOverlapForInvalidOffset);
232 offset = std::max( 337 offset = std::max(
233 offset, -secondary_bounds.height() + kMinimumOverlapForInvalidOffset); 338 offset, -secondary_bounds.height() + kMinimumOverlapForInvalidOffset);
234 } 339 }
235 switch (secondary_display_layout_) { 340 switch (position) {
236 case TOP: 341 case DisplayLayout::TOP:
237 new_secondary_origin.Offset(offset, -secondary_bounds.height()); 342 new_secondary_origin.Offset(offset, -secondary_bounds.height());
238 break; 343 break;
239 case RIGHT: 344 case DisplayLayout::RIGHT:
240 new_secondary_origin.Offset(primary_bounds.width(), offset); 345 new_secondary_origin.Offset(primary_bounds.width(), offset);
241 break; 346 break;
242 case BOTTOM: 347 case DisplayLayout::BOTTOM:
243 new_secondary_origin.Offset(offset, primary_bounds.height()); 348 new_secondary_origin.Offset(offset, primary_bounds.height());
244 break; 349 break;
245 case LEFT: 350 case DisplayLayout::LEFT:
246 new_secondary_origin.Offset(-secondary_bounds.width(), offset); 351 new_secondary_origin.Offset(-secondary_bounds.width(), offset);
247 break; 352 break;
248 } 353 }
249 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); 354 gfx::Insets insets = secondary_display->GetWorkAreaInsets();
250 secondary_display->set_bounds( 355 secondary_display->set_bounds(
251 gfx::Rect(new_secondary_origin, secondary_bounds.size())); 356 gfx::Rect(new_secondary_origin, secondary_bounds.size()));
252 secondary_display->UpdateWorkAreaFromInsets(insets); 357 secondary_display->UpdateWorkAreaFromInsets(insets);
253 } 358 }
254 359
255 } // namespace internal
256 } // namespace ash 360 } // namespace ash
OLDNEW
« no previous file with comments | « ash/display/display_controller.h ('k') | ash/display/display_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698