diff options
Diffstat (limited to 'ui/gfx')
-rw-r--r-- | ui/gfx/monitor.cc | 45 | ||||
-rw-r--r-- | ui/gfx/monitor.h | 76 | ||||
-rw-r--r-- | ui/gfx/monitor_unittest.cc | 29 | ||||
-rw-r--r-- | ui/gfx/screen.h | 64 | ||||
-rw-r--r-- | ui/gfx/screen_android.cc | 5 | ||||
-rw-r--r-- | ui/gfx/screen_ash.cc | 104 | ||||
-rw-r--r-- | ui/gfx/screen_aura.cc | 67 | ||||
-rw-r--r-- | ui/gfx/screen_aurax11.cc | 83 | ||||
-rw-r--r-- | ui/gfx/screen_gtk.cc | 117 | ||||
-rw-r--r-- | ui/gfx/screen_impl.h | 33 | ||||
-rw-r--r-- | ui/gfx/screen_mac.mm | 59 | ||||
-rw-r--r-- | ui/gfx/screen_unittest.cc | 7 | ||||
-rw-r--r-- | ui/gfx/screen_win.cc | 85 |
13 files changed, 431 insertions, 343 deletions
diff --git a/ui/gfx/monitor.cc b/ui/gfx/monitor.cc new file mode 100644 index 0000000..8e56e0f --- /dev/null +++ b/ui/gfx/monitor.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/monitor.h" + +#include "ui/gfx/insets.h" + +namespace gfx { + +Monitor::Monitor() : id_(-1), device_scale_factor_(1.0) { +} + +Monitor::Monitor(int id) : id_(id), device_scale_factor_(1.0) { +} + +Monitor::Monitor(int id, const gfx::Rect& bounds) + : id_(id), + bounds_(bounds), + work_area_(bounds), + device_scale_factor_(1.0) { +} + +Monitor::~Monitor() { +} + +void Monitor::SetBoundsAndUpdateWorkArea(const gfx::Rect& bounds) { + Insets insets(work_area_.y() - bounds_.y(), + work_area_.x() - bounds_.x(), + bounds_.bottom() - work_area_.bottom(), + bounds_.right() - work_area_.right()); + bounds_ = bounds; + UpdateWorkAreaWithInsets(insets); +} + +void Monitor::SetSizeAndUpdateWorkArea(const gfx::Size& size) { + SetBoundsAndUpdateWorkArea(gfx::Rect(bounds_.origin(), size)); +} + +void Monitor::UpdateWorkAreaWithInsets(const gfx::Insets& insets) { + work_area_ = bounds_; + work_area_.Inset(insets); +} + +} // namespace gfx diff --git a/ui/gfx/monitor.h b/ui/gfx/monitor.h new file mode 100644 index 0000000..3110acd --- /dev/null +++ b/ui/gfx/monitor.h @@ -0,0 +1,76 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_MONITOR_H_ +#define UI_GFX_MONITOR_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ui/base/ui_export.h" +#include "ui/gfx/rect.h" + +namespace gfx { + +// Note: The screen and monitor currently uses pixel coordinate +// system. ENABLE_DIP macro (which is enabled with enable_dip=1 gyp +// flag) will make this inconsistent with views' coordinate system +// because views will use DIP coordinate system, which uses +// (1.0/device_scale_factor) scale of the pixel coordinate system. +// TODO(oshima): Change aura/screen to DIP coordinate system and +// update this comment. +class UI_EXPORT Monitor { + public: + // Creates a monitor with invalid id(-1) as default. + Monitor(); + explicit Monitor(int id); + Monitor(int id, const Rect& bounds); + ~Monitor(); + + // Sets/Gets unique identifier associated with the monitor. + int id() const { return id_; } + void set_id(int id) { id_ = id; } + + // Gets/Sets the monitor's bounds in gfx::Screen's coordinates. + // -1 means invalid monitor and it doesn't not exit. + const Rect& bounds() const { return bounds_; } + void set_bounds(const Rect& bounds) { bounds_ = bounds; } + + // Gets/Sets the monitor's work area in gfx::Screen's coordinates. + const Rect& work_area() const { return work_area_; } + void set_work_area(const Rect& work_area) { work_area_ = work_area; } + + // Output device's pixel scale factor. This specifies how much the + // UI should be scaled when the actual output has more pixels than + // standard monitors (which is around 100~120dpi.) The potential return + // values depend on each platforms. + float device_scale_factor() const { return device_scale_factor_; } + void set_device_scale_factor(float scale) { device_scale_factor_ = scale; } + + // Utility functions that just return the size of monitor and + // work area. + const Size& size() const { return bounds_.size(); } + const Size& work_area_size() const { return work_area_.size(); } + + // Sets the monitor bounds and updates the work are using the same insets + // between old bounds and work area. + void SetBoundsAndUpdateWorkArea(const gfx::Rect& bounds); + + // Sets the monitor size and updates the work are using the same insets + // between old bounds and work area. + void SetSizeAndUpdateWorkArea(const gfx::Size& size); + + // Computes and updates the monitor's work are using insets and the bounds. + void UpdateWorkAreaWithInsets(const gfx::Insets& work_area_insets); + + private: + int id_; + Rect bounds_; + Rect work_area_; + float device_scale_factor_; +}; + +} // namespace gfx + +#endif // UI_GFX_MONITOR_H_ diff --git a/ui/gfx/monitor_unittest.cc b/ui/gfx/monitor_unittest.cc new file mode 100644 index 0000000..24f179b --- /dev/null +++ b/ui/gfx/monitor_unittest.cc @@ -0,0 +1,29 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/monitor.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/insets.h" + +namespace { + +TEST(MonitorTest, WorkArea) { + gfx::Monitor monitor(0, gfx::Rect(0, 0, 100, 100)); + EXPECT_EQ("0,0 100x100", monitor.work_area().ToString()); + + monitor.set_work_area(gfx::Rect(3, 4, 90, 80)); + EXPECT_EQ("3,4 90x80", monitor.work_area().ToString()); + + monitor.SetBoundsAndUpdateWorkArea(gfx::Rect(10, 20, 50, 50)); + EXPECT_EQ("13,24 40x30", monitor.work_area().ToString()); + + monitor.SetSizeAndUpdateWorkArea(gfx::Size(200, 200)); + EXPECT_EQ("13,24 190x180", monitor.work_area().ToString()); + + monitor.UpdateWorkAreaWithInsets(gfx::Insets(3, 4, 5, 6)); + EXPECT_EQ("14,23 190x192", monitor.work_area().ToString()); +} + +} diff --git a/ui/gfx/screen.h b/ui/gfx/screen.h index a451130..8e5d273 100644 --- a/ui/gfx/screen.h +++ b/ui/gfx/screen.h @@ -7,82 +7,48 @@ #pragma once #include "ui/gfx/native_widget_types.h" +#include "ui/gfx/monitor.h" #include "ui/gfx/point.h" -#include "ui/gfx/rect.h" -#include "ui/gfx/size.h" namespace gfx { +class Rect; +class ScreenImpl; // A utility class for getting various info about screen size, monitors, // cursor position, etc. -// TODO(erikkay) add more of those methods here class UI_EXPORT Screen { public: virtual ~Screen() {} -#if defined(USE_ASH) +#if defined(USE_AURA) // Sets the instance to use. This takes owernship of |screen|, deleting the // old instance. This is used on aura to avoid circular dependencies between // ui and aura. - static void SetInstance(Screen* screen); + static void SetInstance(ScreenImpl* screen); #endif // Returns the current absolute position of the mouse pointer. static gfx::Point GetCursorScreenPoint(); - // Returns the work area of the monitor nearest the specified window. - static gfx::Rect GetMonitorWorkAreaNearestWindow(gfx::NativeView view); - - // Returns the bounds of the monitor nearest the specified window. - static gfx::Rect GetMonitorAreaNearestWindow(gfx::NativeView view); - - // Returns the work area of the monitor nearest the specified point. - static gfx::Rect GetMonitorWorkAreaNearestPoint(const gfx::Point& point); - - // Returns the monitor area (not the work area, but the complete bounds) of - // the monitor nearest the specified point. - static gfx::Rect GetMonitorAreaNearestPoint(const gfx::Point& point); - - // Returns the bounds of the work area of the primary monitor. - static gfx::Rect GetPrimaryMonitorWorkArea(); - - // Returns the bounds of the primary monitor. - static gfx::Rect GetPrimaryMonitorBounds(); - - // Returns the bounds of the work area of the monitor that most closely - // intersects the provided bounds. - static gfx::Rect GetMonitorWorkAreaMatching( - const gfx::Rect& match_rect); - // Returns the window under the cursor. static gfx::NativeWindow GetWindowAtCursorScreenPoint(); - // Returns the dimensions of the primary monitor in pixels. - static gfx::Size GetPrimaryMonitorSize(); - // Returns the number of monitors. // Mirrored displays are excluded; this method is intended to return the // number of distinct, usable displays. static int GetNumMonitors(); - protected: - virtual gfx::Point GetCursorScreenPointImpl() = 0; - virtual gfx::Rect GetMonitorWorkAreaNearestWindowImpl( - gfx::NativeView view) = 0; - virtual gfx::Rect GetMonitorAreaNearestWindowImpl( - gfx::NativeView view) = 0; - virtual gfx::Rect GetMonitorWorkAreaNearestPointImpl( - const gfx::Point& point) = 0; - virtual gfx::Rect GetMonitorAreaNearestPointImpl(const gfx::Point& point) = 0; - virtual gfx::NativeWindow GetWindowAtCursorScreenPointImpl() = 0; - virtual gfx::Size GetPrimaryMonitorSizeImpl() = 0; - virtual int GetNumMonitorsImpl() = 0; + // Returns the monitor nearest the specified window. + static gfx::Monitor GetMonitorNearestWindow(gfx::NativeView view); -private: -#if defined(USE_AURA) - // The singleton screen instance. Only used on aura. - static Screen* instance_; -#endif + // Returns the the monitor nearest the specified point. + static gfx::Monitor GetMonitorNearestPoint(const gfx::Point& point); + + // Returns the bounds of the work area of the primary monitor. + static gfx::Monitor GetPrimaryMonitor(); + + // Returns the monitor that most closely intersects the provided bounds. + static gfx::Monitor GetMonitorMatching(const gfx::Rect& match_rect); }; } // namespace gfx diff --git a/ui/gfx/screen_android.cc b/ui/gfx/screen_android.cc index 27a60c1..2d1fd91 100644 --- a/ui/gfx/screen_android.cc +++ b/ui/gfx/screen_android.cc @@ -5,13 +5,14 @@ #include "ui/gfx/screen.h" #include "base/logging.h" +#include "ui/gfx/monitor.h" namespace gfx { // static -gfx::Size Screen::GetPrimaryMonitorSize() { +gfx::Monitor Screen::GetPrimaryMonitor() { NOTIMPLEMENTED() << "crbug.com/117839 tracks implementation"; - return gfx::Size(1, 1); + return gfx::Monitor(0, gfx::Rect(0, 0, 1, 1)); } // static diff --git a/ui/gfx/screen_ash.cc b/ui/gfx/screen_ash.cc deleted file mode 100644 index 091c2b0..0000000 --- a/ui/gfx/screen_ash.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gfx/screen.h" - -#include "base/logging.h" -#include "ui/gfx/native_widget_types.h" - -namespace gfx { - -// gfx can't depend upon ash, otherwise we have circular dependencies. So, -// gfx::Screen is pluggable and Desktop plugs in the real implementation. - -// static -Screen* Screen::instance_ = NULL; - -// static -void Screen::SetInstance(Screen* screen) { - delete instance_; - instance_ = screen; -} - -// static -gfx::Point Screen::GetCursorScreenPoint() { - // TODO(erg): Figure out what to do about the Screen class. For now, I've - // added default values for when a Screen instance class isn't passed in, but - // this is the wrong thing. - if (!instance_) - return gfx::Point(); - return instance_->GetCursorScreenPointImpl(); -} - -// static -gfx::Rect Screen::GetMonitorWorkAreaNearestWindow(gfx::NativeWindow window) { - if (!instance_) - return gfx::Rect(0, 0, 800, 800); - return instance_->GetMonitorWorkAreaNearestWindowImpl(window); -} - -// static -gfx::Rect Screen::GetMonitorAreaNearestWindow(gfx::NativeWindow window) { - if (!instance_) - return gfx::Rect(0, 0, 800, 800); - return instance_->GetMonitorAreaNearestWindowImpl(window); -} - -// static -gfx::Rect Screen::GetMonitorWorkAreaNearestPoint(const gfx::Point& point) { - if (!instance_) - return gfx::Rect(0, 0, 800, 800); - return instance_->GetMonitorWorkAreaNearestPointImpl(point); -} - -// static -gfx::Rect Screen::GetMonitorAreaNearestPoint(const gfx::Point& point) { - if (!instance_) - return gfx::Rect(0, 0, 800, 800); - return instance_->GetMonitorAreaNearestPointImpl(point); -} - -// static -gfx::Rect Screen::GetPrimaryMonitorWorkArea() { - if (!instance_) - return gfx::Rect(0, 0, 800, 800); - return instance_->GetMonitorWorkAreaNearestPoint(gfx::Point()); -} - -// static -gfx::Rect Screen::GetPrimaryMonitorBounds() { - if (!instance_) - return gfx::Rect(0, 0, 800, 800); - return instance_->GetMonitorAreaNearestPoint(gfx::Point()); -} - -// static -gfx::Rect Screen::GetMonitorWorkAreaMatching(const gfx::Rect& match_rect) { - if (!instance_) - return gfx::Rect(0, 0, 800, 800); - return instance_->GetMonitorWorkAreaNearestPoint(gfx::Point()); -} - -// static -gfx::NativeWindow Screen::GetWindowAtCursorScreenPoint() { - if (!instance_) - return NULL; - return instance_->GetWindowAtCursorScreenPointImpl(); -} - -// static -gfx::Size Screen::GetPrimaryMonitorSize() { - if (!instance_) - return gfx::Size(800, 800); - return instance_->GetPrimaryMonitorSizeImpl(); -} - -// static -int Screen::GetNumMonitors() { - if (!instance_) - return 1; - return instance_->GetNumMonitorsImpl(); -} - -} // namespace gfx diff --git a/ui/gfx/screen_aura.cc b/ui/gfx/screen_aura.cc new file mode 100644 index 0000000..1631095 --- /dev/null +++ b/ui/gfx/screen_aura.cc @@ -0,0 +1,67 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/screen.h" + +#include "base/logging.h" +#include "ui/gfx/monitor.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/gfx/screen_impl.h" + +namespace gfx { + +// gfx can't depend upon aura, otherwise we have circular dependencies. So, +// gfx::Screen is pluggable and Desktop plugs in the real implementation. +namespace { +ScreenImpl* g_instance_ = NULL; +} + +// static +void Screen::SetInstance(ScreenImpl* screen) { + delete g_instance_; + g_instance_ = screen; +} + +#if defined(USE_ASH) +// TODO(oshima): Implement ScreenImpl for Linux/aura and remove this +// ifdef. + +// static +Point Screen::GetCursorScreenPoint() { + return g_instance_->GetCursorScreenPoint(); +} + +// static +NativeWindow Screen::GetWindowAtCursorScreenPoint() { + return g_instance_->GetWindowAtCursorScreenPoint(); +} + +// static +int Screen::GetNumMonitors() { + return g_instance_->GetNumMonitors(); +} + +// static +Monitor Screen::GetMonitorNearestWindow(NativeView window) { + return g_instance_->GetMonitorNearestWindow(window); +} + +// static +Monitor Screen::GetMonitorNearestPoint(const Point& point) { + return g_instance_->GetMonitorNearestPoint(point); +} + +// static +Monitor Screen::GetPrimaryMonitor() { + return g_instance_->GetPrimaryMonitor(); +} + +// static +Monitor Screen::GetMonitorMatching(const gfx::Rect& match_rect) { + return g_instance_->GetMonitorNearestPoint(match_rect.CenterPoint()); +} + +#endif + +} // namespace gfx diff --git a/ui/gfx/screen_aurax11.cc b/ui/gfx/screen_aurax11.cc index 03b4e4e..0f16bfe 100644 --- a/ui/gfx/screen_aurax11.cc +++ b/ui/gfx/screen_aurax11.cc @@ -12,10 +12,21 @@ #if !defined(USE_ASH) namespace gfx { +namespace { +gfx::Size Screen::GetPrimaryMonitorSize() { + ::Display* display = ui::GetXDisplay(); + ::Screen* screen = DefaultScreenOfDisplay(display); + int width = WidthOfScreen(screen); + int height = HeightOfScreen(screen); + + return gfx::Size(width, height); +} +} // namespace // TODO(piman,erg): This file needs to be rewritten by someone who understands // the subtlety of X11. That is not erg. +// static gfx::Point Screen::GetCursorScreenPoint() { Display* display = ui::GetXDisplay(); @@ -36,67 +47,45 @@ gfx::Point Screen::GetCursorScreenPoint() { return gfx::Point(root_x, root_y); } -gfx::Rect Screen::GetMonitorWorkAreaNearestWindow( - gfx::NativeView view) { - // TODO(erg): There was a comment about how we shouldn't use _NET_WORKAREA - // here by danakj@. - return GetMonitorAreaNearestWindow(view); -} - -gfx::Rect Screen::GetMonitorAreaNearestWindow(gfx::NativeView view) { - // TODO(erg): Yet another stub. - return GetPrimaryMonitorBounds(); -} - // static -gfx::Rect Screen::GetMonitorWorkAreaNearestPoint(const gfx::Point& point) { - // TODO(jamiewalch): Restrict this to the work area of the monitor. - return GetMonitorAreaNearestPoint(point); +gfx::NativeWindow Screen::GetWindowAtCursorScreenPoint() { + // TODO(erg): I have no clue. May need collaboration with + // RootWindowHostLinux? + return NULL; } // static -gfx::Rect Screen::GetMonitorAreaNearestPoint(const gfx::Point& point) { - // TODO(erg): gdk actually has a description for this! We can implement this - // one. - return GetPrimaryMonitorBounds(); -} - -gfx::Rect Screen::GetPrimaryMonitorWorkArea() { - // TODO(erg): Also needs a real implementation. - return gfx::Rect(gfx::Point(0, 0), GetPrimaryMonitorSize()); -} - -gfx::Rect Screen::GetPrimaryMonitorBounds() { - // TODO(erg): Probably needs to be smarter? - return gfx::Rect(gfx::Point(0, 0), GetPrimaryMonitorSize()); +int Screen::GetNumMonitors() { + // TODO(erg): Figure this out with oshima or piman because I have no clue + // about the Xinerama implications here. + return 1; } -gfx::Rect Screen::GetMonitorWorkAreaMatching(const gfx::Rect& match_rect) { +// static +Monitor Screen::GetMonitorNearestWindow(NativeWindow window) { // TODO(erg): We need to eventually support multiple monitors. - return GetPrimaryMonitorWorkArea(); + return GetPrimaryMonitor(); } -gfx::NativeWindow Screen::GetWindowAtCursorScreenPoint() { - // TODO(erg): I have no clue. May need collaboration with - // RootWindowHostLinux? - return NULL; +// static +Monitor Screen::GetMonitorNearestPoint(const Point& point) { + // TODO(erg): We need to eventually support multiple monitors. + return GetPrimaryMonitor(); } -gfx::Size Screen::GetPrimaryMonitorSize() { - ::Display* display = ui::GetXDisplay(); - ::Screen* screen = DefaultScreenOfDisplay(display); - int width = WidthOfScreen(screen); - int height = HeightOfScreen(screen); - - return gfx::Size(width, height); +// static +Monitor Screen::GetPrimaryMonitor() { + // TODO(erg): There was a comment about how we shouldn't use _NET_WORKAREA + // for work area by danakj@. + // TODO(jamiewalch): Restrict work area to the actual work area of + // the monitor. + return Monitor(gfx::Rect(GetPrimaryMonitorSize())); } -int Screen::GetNumMonitors() { - // TODO(erg): Figure this out with oshima or piman because I have no clue - // about the Xinerama implications here. - return 1; +// static +Monitor Screen::GetMonitorMatching(const gfx::Rect& match_rect) { + return GetPrimaryMonitor(); } } // namespace gfx - #endif // !defined(USE_ASH) diff --git a/ui/gfx/screen_gtk.cc b/ui/gfx/screen_gtk.cc index 1607cc8..1ae8261 100644 --- a/ui/gfx/screen_gtk.cc +++ b/ui/gfx/screen_gtk.cc @@ -8,6 +8,7 @@ #include <gtk/gtk.h> #include "base/logging.h" +#include "ui/gfx/monitor.h" namespace { @@ -46,33 +47,14 @@ bool GetScreenWorkArea(gfx::Rect* out_rect) { return true; } -} // namespace - -namespace gfx { - -// static -gfx::Point Screen::GetCursorScreenPoint() { - gint x, y; - gdk_display_get_pointer(gdk_display_get_default(), NULL, &x, &y, NULL); - return gfx::Point(x, y); -} - -// static -gfx::Rect Screen::GetMonitorWorkAreaNearestWindow(gfx::NativeView view) { - // Do not use the _NET_WORKAREA here, this is supposed to be an area on a - // specific monitor, and _NET_WORKAREA is a hint from the WM that generally - // spans across all monitors. This would make the work area larger than the - // monitor. - // TODO(danakj) This is a work-around as there is no standard way to get this - // area, but it is a rect that we should be computing. The standard means - // to compute this rect would be to watch all windows with - // _NET_WM_STRUT(_PARTIAL) hints, and subtract their space from the physical - // area of the monitor to construct a work area. - return GetMonitorAreaNearestWindow(view); +gfx::Rect NativePrimaryMonitorBounds() { + GdkScreen* screen = gdk_screen_get_default(); + GdkRectangle rect; + gdk_screen_get_monitor_geometry(screen, 0, &rect); + return gfx::Rect(rect); } -// static -gfx::Rect Screen::GetMonitorAreaNearestWindow(gfx::NativeView view) { +gfx::Rect GetMonitorAreaNearestWindow(gfx::NativeView view) { GdkScreen* screen = gdk_screen_get_default(); gint monitor_num = 0; if (view) { @@ -89,43 +71,15 @@ gfx::Rect Screen::GetMonitorAreaNearestWindow(gfx::NativeView view) { return gfx::Rect(bounds); } -// static -gfx::Rect Screen::GetMonitorWorkAreaNearestPoint(const gfx::Point& point) { - // TODO(jamiewalch): Restrict this to the work area of the monitor. - return GetMonitorAreaNearestPoint(point); -} - -// static -gfx::Rect Screen::GetMonitorAreaNearestPoint(const gfx::Point& point) { - GdkScreen* screen = gdk_screen_get_default(); - gint monitor = gdk_screen_get_monitor_at_point(screen, point.x(), point.y()); - GdkRectangle bounds; - gdk_screen_get_monitor_geometry(screen, monitor, &bounds); - return gfx::Rect(bounds); -} - -// static -gfx::Rect Screen::GetPrimaryMonitorWorkArea() { - gfx::Rect rect; - if (GetScreenWorkArea(&rect)) - return rect.Intersect(GetPrimaryMonitorBounds()); - - // Return the best we've got. - return GetPrimaryMonitorBounds(); -} +} // namespace -// static -gfx::Rect Screen::GetPrimaryMonitorBounds() { - GdkScreen* screen = gdk_screen_get_default(); - GdkRectangle rect; - gdk_screen_get_monitor_geometry(screen, 0, &rect); - return gfx::Rect(rect); -} +namespace gfx { // static -gfx::Rect Screen::GetMonitorWorkAreaMatching(const gfx::Rect& match_rect) { - // TODO(thestig) Implement multi-monitor support. - return GetPrimaryMonitorWorkArea(); +gfx::Point Screen::GetCursorScreenPoint() { + gint x, y; + gdk_display_get_pointer(gdk_display_get_default(), NULL, &x, &y, NULL); + return gfx::Point(x, y); } // static @@ -144,9 +98,50 @@ gfx::NativeWindow Screen::GetWindowAtCursorScreenPoint() { } // static -gfx::Size Screen::GetPrimaryMonitorSize() { +gfx::Monitor Screen::GetMonitorNearestWindow(gfx::NativeView view) { + gfx::Rect bounds = GetMonitorAreaNearestWindow(view); + // Do not use the _NET_WORKAREA here, this is supposed to be an area on a + // specific monitor, and _NET_WORKAREA is a hint from the WM that generally + // spans across all monitors. This would make the work area larger than the + // monitor. + // TODO(danakj) This is a work-around as there is no standard way to get this + // area, but it is a rect that we should be computing. The standard means + // to compute this rect would be to watch all windows with + // _NET_WM_STRUT(_PARTIAL) hints, and subtract their space from the physical + // area of the monitor to construct a work area. + // TODO(oshima): Implement ID and Observer. + return gfx::Monitor(0, bounds); +} + +// static +gfx::Monitor Screen::GetMonitorNearestPoint(const gfx::Point& point) { GdkScreen* screen = gdk_screen_get_default(); - return gfx::Size(gdk_screen_get_width(screen), gdk_screen_get_height(screen)); + gint monitor = gdk_screen_get_monitor_at_point(screen, point.x(), point.y()); + GdkRectangle bounds; + gdk_screen_get_monitor_geometry(screen, monitor, &bounds); + // TODO(oshima): Implement ID and Observer. + return gfx::Monitor(0, gfx::Rect(bounds)); +} + +// static +gfx::Monitor Screen::GetPrimaryMonitor() { + gfx::Rect bounds = NativePrimaryMonitorBounds(); + // TODO(oshima): Implement ID and Observer. + gfx::Monitor monitor(0, bounds); + gfx::Rect rect; + if (GetScreenWorkArea(&rect)) { + monitor.set_work_area(rect.Intersect(bounds)); + } else { + // Return the best we've got. + monitor.set_work_area(bounds); + } + return monitor; +} + +// static +gfx::Monitor Screen::GetMonitorMatching(const gfx::Rect& match_rect) { + // TODO(thestig) Implement multi-monitor support. + return GetPrimaryMonitor(); } // static diff --git a/ui/gfx/screen_impl.h b/ui/gfx/screen_impl.h new file mode 100644 index 0000000..2511541 --- /dev/null +++ b/ui/gfx/screen_impl.h @@ -0,0 +1,33 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_SCREEN_IMPL_H_ +#define UI_GFX_SCREEN_IMPL_H_ +#pragma once + +#include "ui/gfx/native_widget_types.h" +#include "ui/gfx/monitor.h" +#include "ui/gfx/point.h" + +namespace gfx { + +// A class that provides |gfx::Screen|'s implementation on aura. +class UI_EXPORT ScreenImpl { + public: + virtual ~ScreenImpl() {} + + virtual gfx::Point GetCursorScreenPoint() = 0; + virtual gfx::NativeWindow GetWindowAtCursorScreenPoint() = 0; + + virtual int GetNumMonitors() = 0; + virtual gfx::Monitor GetMonitorNearestWindow( + gfx::NativeView window) const = 0; + virtual gfx::Monitor GetMonitorNearestPoint( + const gfx::Point& point) const = 0; + virtual gfx::Monitor GetPrimaryMonitor() const = 0; +}; + +} // namespace gfx + +#endif // UI_GFX_SCREEN_IMPL_H_ diff --git a/ui/gfx/screen_mac.mm b/ui/gfx/screen_mac.mm index a3b7306d..64dbf86 100644 --- a/ui/gfx/screen_mac.mm +++ b/ui/gfx/screen_mac.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,6 +7,9 @@ #import <ApplicationServices/ApplicationServices.h> #import <Cocoa/Cocoa.h> +#include "base/logging.h" +#include "ui/gfx/monitor.h" + namespace { gfx::Rect ConvertCoordinateSystem(NSRect ns_rect) { @@ -38,6 +41,25 @@ NSScreen* GetMatchingScreen(const gfx::Rect& match_rect) { return max_screen; } +gfx::Monitor GetMonitorForScreen(NSScreen* screen, bool is_primary) { + NSRect frame = [screen frame]; + // TODO(oshima): Implement ID and Observer. + gfx::Monitor monitor(0, gfx::Rect(NSRectToCGRect(frame))); + + NSRect visible_frame = [screen visibleFrame]; + + // Convert work area's coordinate systems. + if (is_primary) { + gfx::Rect work_area = gfx::Rect(NSRectToCGRect(visible_frame)); + work_area.set_y(frame.size.height - visible_frame.origin.y - + visible_frame.size.height); + monitor.set_work_area(work_area); + } else { + monitor.set_work_area(ConvertCoordinateSystem(visible_frame)); + } + return monitor; +} + } // namespace namespace gfx { @@ -52,39 +74,24 @@ gfx::Point Screen::GetCursorScreenPoint() { } // static -gfx::Rect Screen::GetPrimaryMonitorWorkArea() { +gfx::Monitor Screen::GetPrimaryMonitor() { // Primary monitor is defined as the monitor with the menubar, // which is always at index 0. NSScreen* primary = [[NSScreen screens] objectAtIndex:0]; - NSRect frame = [primary frame]; - NSRect visible_frame = [primary visibleFrame]; + gfx::Monitor monitor = GetMonitorForScreen(primary, true /* primary */); - // Convert coordinate systems. - gfx::Rect rect = gfx::Rect(NSRectToCGRect(visible_frame)); - rect.set_y(frame.size.height - visible_frame.origin.y - - visible_frame.size.height); - return rect; -} - -// static -gfx::Rect Screen::GetPrimaryMonitorBounds() { - // Primary monitor is defined as the monitor with the menubar, - // which is always at index 0. - NSScreen* primary = [[NSScreen screens] objectAtIndex:0]; - return gfx::Rect(NSRectToCGRect([primary frame])); + CGDirectDisplayID main_display = CGMainDisplayID(); + CHECK_EQ(static_cast<const int>(CGDisplayPixelsWide(main_display)), + monitor.size().width()); + CHECK_EQ(static_cast<const int>(CGDisplayPixelsHigh(main_display)), + monitor.size().height()); + return monitor; } // static -gfx::Rect Screen::GetMonitorWorkAreaMatching(const gfx::Rect& match_rect) { +gfx::Monitor Screen::GetMonitorMatching(const gfx::Rect& match_rect) { NSScreen* match_screen = GetMatchingScreen(match_rect); - return ConvertCoordinateSystem([match_screen visibleFrame]); -} - -// static -gfx::Size Screen::GetPrimaryMonitorSize() { - CGDirectDisplayID main_display = CGMainDisplayID(); - return gfx::Size(CGDisplayPixelsWide(main_display), - CGDisplayPixelsHigh(main_display)); + return GetMonitorForScreen(match_screen, false /* may not be primary */); } // static diff --git a/ui/gfx/screen_unittest.cc b/ui/gfx/screen_unittest.cc index 6d1f9f2..5406697 100644 --- a/ui/gfx/screen_unittest.cc +++ b/ui/gfx/screen_unittest.cc @@ -1,17 +1,18 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/screen.h" +#include "testing/gtest/include/gtest/gtest.h" + namespace { typedef testing::Test ScreenTest; TEST_F(ScreenTest, GetPrimaryMonitorSize) { // We aren't actually testing that it's correct, just that it's sane. - const gfx::Size size = gfx::Screen::GetPrimaryMonitorSize(); + const gfx::Size size = gfx::Screen::GetPrimaryMonitor().size(); EXPECT_GE(size.width(), 1); EXPECT_GE(size.height(), 1); } diff --git a/ui/gfx/screen_win.cc b/ui/gfx/screen_win.cc index ea74c82..4487c61 100644 --- a/ui/gfx/screen_win.cc +++ b/ui/gfx/screen_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,6 +6,9 @@ #include <windows.h> +#include "base/logging.h" +#include "ui/gfx/monitor.h" + namespace { MONITORINFO GetMonitorInfoForMonitor(HMONITOR monitor) { @@ -15,6 +18,13 @@ MONITORINFO GetMonitorInfoForMonitor(HMONITOR monitor) { return monitor_info; } +gfx::Monitor GetMonitor(MONITORINFO& monitor_info) { + // TODO(oshima): Implement ID and Observer. + gfx::Monitor monitor(0, gfx::Rect(monitor_info.rcMonitor)); + monitor.set_work_area(gfx::Rect(monitor_info.rcWork)); + return monitor; +} + } // namespace namespace gfx { @@ -27,79 +37,52 @@ gfx::Point Screen::GetCursorScreenPoint() { } // static -gfx::Rect Screen::GetMonitorWorkAreaNearestWindow(gfx::NativeWindow window) { - MONITORINFO monitor_info; - monitor_info.cbSize = sizeof(monitor_info); - GetMonitorInfo(MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST), - &monitor_info); - return gfx::Rect(monitor_info.rcWork); +gfx::NativeWindow Screen::GetWindowAtCursorScreenPoint() { + POINT location; + return GetCursorPos(&location) ? WindowFromPoint(location) : NULL; } // static -gfx::Rect Screen::GetMonitorAreaNearestWindow(gfx::NativeWindow window) { +int Screen::GetNumMonitors() { + return GetSystemMetrics(SM_CMONITORS); +} + +// static +gfx::Monitor Screen::GetMonitorNearestWindow(gfx::NativeWindow window) { MONITORINFO monitor_info; monitor_info.cbSize = sizeof(monitor_info); GetMonitorInfo(MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST), &monitor_info); - return gfx::Rect(monitor_info.rcMonitor); + return GetMonitor(monitor_info); } -static gfx::Rect GetMonitorAreaOrWorkAreaNearestPoint(const gfx::Point& point, - bool work_area) { +// static +gfx::Monitor Screen::GetMonitorNearestPoint(const gfx::Point& point) { POINT initial_loc = { point.x(), point.y() }; HMONITOR monitor = MonitorFromPoint(initial_loc, MONITOR_DEFAULTTONEAREST); MONITORINFO mi = {0}; mi.cbSize = sizeof(mi); if (monitor && GetMonitorInfo(monitor, &mi)) - return gfx::Rect(work_area ? mi.rcWork : mi.rcMonitor); - return gfx::Rect(); + return GetMonitor(mi); + return gfx::Monitor(); } // static -gfx::Rect Screen::GetMonitorWorkAreaNearestPoint(const gfx::Point& point) { - return GetMonitorAreaOrWorkAreaNearestPoint(point, true); +gfx::Monitor Screen::GetPrimaryMonitor() { + MONITORINFO mi = GetMonitorInfoForMonitor( + MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY)); + gfx::Monitor monitor = GetMonitor(mi); + DCHECK_EQ(GetSystemMetrics(SM_CXSCREEN), monitor.size().width()); + DCHECK_EQ(GetSystemMetrics(SM_CYSCREEN), monitor.size().height()); + return monitor; } // static -gfx::Rect Screen::GetMonitorAreaNearestPoint(const gfx::Point& point) { - return GetMonitorAreaOrWorkAreaNearestPoint(point, false); -} - -// static -gfx::Rect Screen::GetPrimaryMonitorWorkArea() { - return gfx::Rect(GetMonitorInfoForMonitor(MonitorFromWindow(NULL, - MONITOR_DEFAULTTOPRIMARY)).rcWork); -} - -// static -gfx::Rect Screen::GetPrimaryMonitorBounds() { - return gfx::Rect(GetMonitorInfoForMonitor(MonitorFromWindow(NULL, - MONITOR_DEFAULTTOPRIMARY)).rcMonitor); -} - -// static -gfx::Rect Screen::GetMonitorWorkAreaMatching(const gfx::Rect& match_rect) { +gfx::Monitor Screen::GetMonitorMatching(const gfx::Rect& match_rect) { RECT other_bounds_rect = match_rect.ToRECT(); MONITORINFO monitor_info = GetMonitorInfoForMonitor(MonitorFromRect( &other_bounds_rect, MONITOR_DEFAULTTONEAREST)); - return gfx::Rect(monitor_info.rcWork); -} - -// static -gfx::NativeWindow Screen::GetWindowAtCursorScreenPoint() { - POINT location; - return GetCursorPos(&location) ? WindowFromPoint(location) : NULL; -} - -// static -gfx::Size Screen::GetPrimaryMonitorSize() { - return gfx::Size(GetSystemMetrics(SM_CXSCREEN), - GetSystemMetrics(SM_CYSCREEN)); -} - -// static -int Screen::GetNumMonitors() { - return GetSystemMetrics(SM_CMONITORS); + return GetMonitor(monitor_info); } } // namespace gfx |