diff options
Diffstat (limited to 'ash/monitor/multi_monitor_manager.cc')
-rw-r--r-- | ash/monitor/multi_monitor_manager.cc | 137 |
1 files changed, 76 insertions, 61 deletions
diff --git a/ash/monitor/multi_monitor_manager.cc b/ash/monitor/multi_monitor_manager.cc index 46dddad..e03219d 100644 --- a/ash/monitor/multi_monitor_manager.cc +++ b/ash/monitor/multi_monitor_manager.cc @@ -12,40 +12,36 @@ #include "base/string_split.h" #include "ui/aura/aura_switches.h" #include "ui/aura/env.h" -#include "ui/aura/monitor.h" #include "ui/aura/root_window.h" #include "ui/aura/root_window_host.h" -#include "ui/gfx/rect.h" #include "ui/aura/window_property.h" +#include "ui/gfx/monitor.h" +#include "ui/gfx/rect.h" -DECLARE_WINDOW_PROPERTY_TYPE(aura::Monitor*); +DECLARE_WINDOW_PROPERTY_TYPE(int); namespace ash { namespace internal { namespace { - -aura::Monitor* Copy(aura::Monitor* m) { - aura::Monitor* monitor = new aura::Monitor; - monitor->set_bounds(m->bounds()); - return monitor; +gfx::Monitor& GetInvalidMonitor() { + static gfx::Monitor* invalid_monitor = new gfx::Monitor(); + return *invalid_monitor; } - } // namespace -DEFINE_WINDOW_PROPERTY_KEY(aura::Monitor*, kMonitorKey, NULL); - -using std::string; -using std::vector; -using aura::Monitor; using aura::RootWindow; using aura::Window; +using gfx::Monitor; +using std::string; +using std::vector; + +DEFINE_WINDOW_PROPERTY_KEY(int, kMonitorIdKey, -1); MultiMonitorManager::MultiMonitorManager() { Init(); } MultiMonitorManager::~MultiMonitorManager() { - STLDeleteContainerPointers(monitors_.begin(), monitors_.end()); } // static @@ -62,20 +58,22 @@ void MultiMonitorManager::CycleMonitor() { } void MultiMonitorManager::OnNativeMonitorsChanged( - const std::vector<const aura::Monitor*>& new_monitors) { + const std::vector<Monitor>& new_monitors) { size_t min = std::min(monitors_.size(), new_monitors.size()); // For m19, we only care about 1st monitor as primary, and // don't differentiate the rest of monitors as all secondary - // monitors have the same content. + // monitors have the same content. ID for primary monitor stays the same + // because we never remove it, we don't update IDs for other monitors + // , for now, because they're the same. // TODO(oshima): Fix this so that we can differentiate outputs // and keep a content on one monitor stays on the same monitor // when a monitor is added or removed. for (size_t i = 0; i < min; ++i) { - Monitor* current_monitor = monitors_[i]; - const Monitor* new_monitor = new_monitors[i]; - if (current_monitor->bounds() != new_monitor->bounds()) { - current_monitor->set_bounds(new_monitor->bounds()); + Monitor& current_monitor = monitors_[i]; + const Monitor& new_monitor = new_monitors[i]; + if (current_monitor.bounds() != new_monitor.bounds()) { + current_monitor.SetBoundsAndUpdateWorkArea(new_monitor.bounds()); NotifyBoundsChanged(current_monitor); } } @@ -83,9 +81,10 @@ void MultiMonitorManager::OnNativeMonitorsChanged( if (monitors_.size() < new_monitors.size()) { // New monitors added for (size_t i = min; i < new_monitors.size(); ++i) { - Monitor* monitor = new Monitor(); - monitor->set_bounds(new_monitors[i]->bounds()); - monitors_.push_back(monitor); + // + monitors_.push_back(Monitor(i)); + gfx::Monitor& monitor = monitors_.back(); + monitor.SetBoundsAndUpdateWorkArea(new_monitors[i].bounds()); NotifyMonitorAdded(monitor); } } else { @@ -93,35 +92,45 @@ void MultiMonitorManager::OnNativeMonitorsChanged( // monitor (at index 0) because it needs the monitor information // even if it doesn't exit. while (monitors_.size() > new_monitors.size() && monitors_.size() > 1) { - Monitor* monitor = monitors_.back(); - NotifyMonitorRemoved(monitor); - monitors_.erase(std::find(monitors_.begin(), monitors_.end(), monitor)); - delete monitor; + Monitors::reverse_iterator iter = monitors_.rbegin(); + NotifyMonitorRemoved(*iter); + monitors_.erase(iter.base() - 1); } } } RootWindow* MultiMonitorManager::CreateRootWindowForMonitor( - Monitor* monitor) { - RootWindow* root_window = new RootWindow(monitor->bounds()); + const Monitor& monitor) { + RootWindow* root_window = new RootWindow(monitor.bounds()); // No need to remove RootWindowObserver because // the MonitorManager object outlives RootWindow objects. root_window->AddRootWindowObserver(this); - root_window->SetProperty(kMonitorKey, monitor); + root_window->SetProperty(kMonitorIdKey, monitor.id()); return root_window; } -const Monitor* MultiMonitorManager::GetMonitorNearestWindow( +const Monitor& MultiMonitorManager::GetMonitorAt(size_t index) { + return index < monitors_.size() ? monitors_[index] : GetInvalidMonitor(); +} + +size_t MultiMonitorManager::GetNumMonitors() const { + return monitors_.size(); +} + +const Monitor& MultiMonitorManager::GetMonitorNearestWindow( const Window* window) const { if (!window) { MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); return manager->GetMonitorAt(0); } const RootWindow* root = window->GetRootWindow(); - return root ? root->GetProperty(kMonitorKey) : NULL; + MultiMonitorManager* that = const_cast<MultiMonitorManager*>(this); + return root ? + that->FindMonitorById(root->GetProperty(kMonitorIdKey)) : + GetInvalidMonitor(); } -const Monitor* MultiMonitorManager::GetMonitorNearestPoint( +const Monitor& MultiMonitorManager::GetMonitorNearestPoint( const gfx::Point& point) const { // TODO(oshima): For m19, mouse is constrained within // the primary window. @@ -129,28 +138,26 @@ const Monitor* MultiMonitorManager::GetMonitorNearestPoint( return manager->GetMonitorAt(0); } -Monitor* MultiMonitorManager::GetMonitorAt(size_t index) { - return index < monitors_.size() ? monitors_[index] : NULL; -} - -size_t MultiMonitorManager::GetNumMonitors() const { - return monitors_.size(); -} - -Monitor* MultiMonitorManager::GetMonitorNearestWindow(const Window* window) { - const MonitorManager* manager = this; - return const_cast<Monitor*>(manager->GetMonitorNearestWindow(window)); -} - void MultiMonitorManager::OnRootWindowResized(const aura::RootWindow* root, const gfx::Size& old_size) { if (!use_fullscreen_host_window()) { - Monitor* monitor = root->GetProperty(kMonitorKey); - monitor->set_size(root->GetHostSize()); + int monitor_id = root->GetProperty(kMonitorIdKey); + Monitor& monitor = FindMonitorById(monitor_id); + monitor.SetSizeAndUpdateWorkArea(root->GetHostSize()); NotifyBoundsChanged(monitor); } } +bool MultiMonitorManager::UpdateWorkAreaOfMonitorNearestWindow( + const aura::Window* window, + const gfx::Insets& insets) { + const RootWindow* root = window->GetRootWindow(); + Monitor& monitor = FindMonitorById(root->GetProperty(kMonitorIdKey)); + gfx::Rect old_work_area = monitor.work_area(); + monitor.UpdateWorkAreaWithInsets(insets); + return old_work_area != monitor.work_area(); +} + void MultiMonitorManager::Init() { // TODO(oshima): Move this logic to MonitorChangeObserver. const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( @@ -166,35 +173,43 @@ void MultiMonitorManager::Init() { } void MultiMonitorManager::AddRemoveMonitorImpl() { - std::vector<const Monitor*> new_monitors; + std::vector<Monitor> new_monitors; if (monitors_.size() > 1) { // Remove if there is more than one monitor. int count = monitors_.size() - 1; for (Monitors::const_iterator iter = monitors_.begin(); count-- > 0; ++iter) - new_monitors.push_back(Copy(*iter)); + new_monitors.push_back(*iter); } else { // Add if there is only one monitor. - new_monitors.push_back(Copy(monitors_[0])); - aura::Monitor* extra_monitor = new Monitor; - extra_monitor->set_bounds(gfx::Rect(100, 100, 1440, 800)); - new_monitors.push_back(extra_monitor); + new_monitors.push_back(monitors_[0]); + new_monitors.push_back(CreateMonitorFromSpec("50+50-1280x768")); } if (new_monitors.size()) OnNativeMonitorsChanged(new_monitors); - STLDeleteContainerPointers(new_monitors.begin(), new_monitors.end()); } void MultiMonitorManager::CycleMonitorImpl() { if (monitors_.size() > 1) { - std::vector<const Monitor*> new_monitors; + std::vector<Monitor> new_monitors; for (Monitors::const_iterator iter = monitors_.begin() + 1; - iter != monitors_.end(); ++iter) - new_monitors.push_back(Copy(*iter)); - new_monitors.push_back(Copy(monitors_.front())); + iter != monitors_.end(); ++iter) { + gfx::Monitor monitor = *iter; + new_monitors.push_back(monitor); + } + new_monitors.push_back(monitors_.front()); OnNativeMonitorsChanged(new_monitors); - STLDeleteContainerPointers(new_monitors.begin(), new_monitors.end()); } } +gfx::Monitor& MultiMonitorManager::FindMonitorById(int id) { + for (Monitors::iterator iter = monitors_.begin(); + iter != monitors_.end(); ++iter) { + if ((*iter).id() == id) + return *iter; + } + DLOG(FATAL) << "Could not find monitor by id:" << id; + return GetInvalidMonitor(); +} + } // namespace internal } // namespace ash |