| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/ui/window_sizer.h" |
| 6 |
| 5 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
| 8 |
| 6 #include "chrome/browser/ui/browser.h" | 9 #include "chrome/browser/ui/browser.h" |
| 7 #include "chrome/browser/ui/browser_list.h" | 10 #include "chrome/browser/ui/browser_list.h" |
| 8 #include "chrome/browser/ui/browser_window.h" | 11 #include "chrome/browser/ui/browser_window.h" |
| 9 #include "chrome/browser/ui/window_sizer.h" | |
| 10 | |
| 11 | 12 |
| 12 // How much horizontal and vertical offset there is between newly | 13 // How much horizontal and vertical offset there is between newly |
| 13 // opened windows. | 14 // opened windows. |
| 14 const int WindowSizer::kWindowTilePixels = 22; | 15 const int WindowSizer::kWindowTilePixels = 22; |
| 15 | 16 |
| 16 namespace { | |
| 17 | |
| 18 class DefaultMonitorInfoProvider : public WindowSizer::MonitorInfoProvider { | |
| 19 public: | |
| 20 DefaultMonitorInfoProvider() { } | |
| 21 | |
| 22 // Overridden from WindowSizer::MonitorInfoProvider: | |
| 23 virtual gfx::Rect GetPrimaryMonitorWorkArea() const { | |
| 24 // Primary monitor is defined as the monitor with the menubar, | |
| 25 // which is always at index 0. | |
| 26 NSScreen* primary = [[NSScreen screens] objectAtIndex:0]; | |
| 27 NSRect frame = [primary frame]; | |
| 28 NSRect visible_frame = [primary visibleFrame]; | |
| 29 | |
| 30 // Convert coordinate systems. | |
| 31 gfx::Rect rect = gfx::Rect(NSRectToCGRect(visible_frame)); | |
| 32 rect.set_y(frame.size.height - | |
| 33 visible_frame.origin.y - visible_frame.size.height); | |
| 34 return rect; | |
| 35 } | |
| 36 | |
| 37 virtual gfx::Rect GetPrimaryMonitorBounds() const { | |
| 38 // Primary monitor is defined as the monitor with the menubar, | |
| 39 // which is always at index 0. | |
| 40 NSScreen* primary = [[NSScreen screens] objectAtIndex:0]; | |
| 41 return gfx::Rect(NSRectToCGRect([primary frame])); | |
| 42 } | |
| 43 | |
| 44 virtual gfx::Rect GetMonitorWorkAreaMatching( | |
| 45 const gfx::Rect& match_rect) const { | |
| 46 NSScreen* match_screen = GetMatchingScreen(match_rect); | |
| 47 return ConvertCoordinateSystem([match_screen visibleFrame]); | |
| 48 } | |
| 49 | |
| 50 virtual void UpdateWorkAreas(); | |
| 51 | |
| 52 private: | |
| 53 // Returns a pointer to the screen that most closely matches the | |
| 54 // given |match_rect|. This function currently returns the screen | |
| 55 // that contains the largest amount of |match_rect| by area. | |
| 56 NSScreen* GetMatchingScreen(const gfx::Rect& match_rect) const { | |
| 57 // Default to the monitor with the current keyboard focus, in case | |
| 58 // |match_rect| is not on any screen at all. | |
| 59 NSScreen* max_screen = [NSScreen mainScreen]; | |
| 60 int max_area = 0; | |
| 61 | |
| 62 for (NSScreen* screen in [NSScreen screens]) { | |
| 63 gfx::Rect monitor_area = ConvertCoordinateSystem([screen frame]); | |
| 64 gfx::Rect intersection = monitor_area.Intersect(match_rect); | |
| 65 int area = intersection.width() * intersection.height(); | |
| 66 if (area > max_area) { | |
| 67 max_area = area; | |
| 68 max_screen = screen; | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 return max_screen; | |
| 73 } | |
| 74 | |
| 75 // The lower left corner of screen 0 is always at (0, 0). The | |
| 76 // cross-platform code expects the origin to be in the upper left, | |
| 77 // so we have to translate |ns_rect| to the new coordinate | |
| 78 // system. | |
| 79 gfx::Rect ConvertCoordinateSystem(NSRect ns_rect) const; | |
| 80 | |
| 81 DISALLOW_COPY_AND_ASSIGN(DefaultMonitorInfoProvider); | |
| 82 }; | |
| 83 | |
| 84 void DefaultMonitorInfoProvider::UpdateWorkAreas() { | |
| 85 work_areas_.clear(); | |
| 86 | |
| 87 for (NSScreen* screen in [NSScreen screens]) { | |
| 88 gfx::Rect rect = ConvertCoordinateSystem([screen visibleFrame]); | |
| 89 work_areas_.push_back(rect); | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 gfx::Rect DefaultMonitorInfoProvider::ConvertCoordinateSystem( | |
| 94 NSRect ns_rect) const { | |
| 95 // Primary monitor is defined as the monitor with the menubar, | |
| 96 // which is always at index 0. | |
| 97 NSScreen* primary_screen = [[NSScreen screens] objectAtIndex:0]; | |
| 98 float primary_screen_height = [primary_screen frame].size.height; | |
| 99 gfx::Rect rect(NSRectToCGRect(ns_rect)); | |
| 100 rect.set_y(primary_screen_height - rect.y() - rect.height()); | |
| 101 return rect; | |
| 102 } | |
| 103 | |
| 104 } // namespace | |
| 105 | |
| 106 // static | |
| 107 WindowSizer::MonitorInfoProvider* | |
| 108 WindowSizer::CreateDefaultMonitorInfoProvider() { | |
| 109 return new DefaultMonitorInfoProvider(); | |
| 110 } | |
| 111 | |
| 112 // static | 17 // static |
| 113 gfx::Point WindowSizer::GetDefaultPopupOrigin(const gfx::Size& size) { | 18 gfx::Point WindowSizer::GetDefaultPopupOrigin(const gfx::Size& size) { |
| 114 NSRect work_area = [[NSScreen mainScreen] visibleFrame]; | 19 NSRect work_area = [[NSScreen mainScreen] visibleFrame]; |
| 115 NSRect main_area = [[[NSScreen screens] objectAtIndex:0] frame]; | 20 NSRect main_area = [[[NSScreen screens] objectAtIndex:0] frame]; |
| 116 NSPoint corner = NSMakePoint(NSMinX(work_area), NSMaxY(work_area)); | 21 NSPoint corner = NSMakePoint(NSMinX(work_area), NSMaxY(work_area)); |
| 117 | 22 |
| 118 if (Browser* b = BrowserList::GetLastActive()) { | 23 if (Browser* b = BrowserList::GetLastActive()) { |
| 119 NSWindow* window = b->window()->GetNativeHandle(); | 24 NSWindow* window = b->window()->GetNativeHandle(); |
| 120 NSRect window_frame = [window frame]; | 25 NSRect window_frame = [window frame]; |
| 121 | 26 |
| 122 // Limit to not overflow the work area right and bottom edges. | 27 // Limit to not overflow the work area right and bottom edges. |
| 123 NSPoint limit = NSMakePoint( | 28 NSPoint limit = NSMakePoint( |
| 124 std::min(NSMinX(window_frame) + kWindowTilePixels, | 29 std::min(NSMinX(window_frame) + kWindowTilePixels, |
| 125 NSMaxX(work_area) - size.width()), | 30 NSMaxX(work_area) - size.width()), |
| 126 std::max(NSMaxY(window_frame) - kWindowTilePixels, | 31 std::max(NSMaxY(window_frame) - kWindowTilePixels, |
| 127 NSMinY(work_area) + size.height())); | 32 NSMinY(work_area) + size.height())); |
| 128 | 33 |
| 129 // Adjust corner to now overflow the work area left and top edges, so | 34 // Adjust corner to now overflow the work area left and top edges, so |
| 130 // that if a popup does not fit the title-bar is remains visible. | 35 // that if a popup does not fit the title-bar is remains visible. |
| 131 corner = NSMakePoint(std::max(corner.x, limit.x), | 36 corner = NSMakePoint(std::max(corner.x, limit.x), |
| 132 std::min(corner.y, limit.y)); | 37 std::min(corner.y, limit.y)); |
| 133 } | 38 } |
| 134 | 39 |
| 135 return gfx::Point(corner.x, NSHeight(main_area) - corner.y); | 40 return gfx::Point(corner.x, NSHeight(main_area) - corner.y); |
| 136 } | 41 } |
| OLD | NEW |