From b5898d3355579b6db4600762e6819f30d323f27e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 14 Jan 2015 16:19:22 -0800 Subject: [PATCH] Add events on display add/remove. --- atom.gyp | 1 + atom/browser/api/atom_api_screen.cc | 85 +++++++++++++++++++++++++---- atom/browser/api/atom_api_screen.h | 59 ++++++++++++++++++++ atom/browser/api/lib/screen.coffee | 13 ++--- 4 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 atom/browser/api/atom_api_screen.h diff --git a/atom.gyp b/atom.gyp index c7078bb7db2f..1ab153d05004 100644 --- a/atom.gyp +++ b/atom.gyp @@ -80,6 +80,7 @@ 'atom/browser/api/atom_api_protocol.cc', 'atom/browser/api/atom_api_protocol.h', 'atom/browser/api/atom_api_screen.cc', + 'atom/browser/api/atom_api_screen.h', 'atom/browser/api/atom_api_tray.cc', 'atom/browser/api/atom_api_tray.h', 'atom/browser/api/atom_api_web_contents.cc', diff --git a/atom/browser/api/atom_api_screen.cc b/atom/browser/api/atom_api_screen.cc index 2e3fd3b50074..7d59d46d9ae9 100644 --- a/atom/browser/api/atom_api_screen.cc +++ b/atom/browser/api/atom_api_screen.cc @@ -2,29 +2,92 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. +#include "atom/browser/api/atom_api_screen.h" + +#include "atom/browser/browser.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "base/bind.h" #include "native_mate/dictionary.h" +#include "native_mate/object_template_builder.h" #include "ui/gfx/screen.h" #include "atom/common/node_includes.h" +namespace atom { + +namespace api { + +Screen::Screen(gfx::Screen* screen) : screen_(screen) { +} + +Screen::~Screen() { +} + +gfx::Point Screen::GetCursorScreenPoint() { + return screen_->GetCursorScreenPoint(); +} + +gfx::Display Screen::GetPrimaryDisplay() { + return screen_->GetPrimaryDisplay(); +} + +std::vector Screen::GetAllDisplays() { + return screen_->GetAllDisplays(); +} + +gfx::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) { + return screen_->GetDisplayNearestPoint(point); +} + +gfx::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) { + return screen_->GetDisplayMatching(match_rect); +} + +void Screen::OnDisplayAdded(const gfx::Display& new_display) { + Emit("display-added"); +} + +void Screen::OnDisplayRemoved(const gfx::Display& old_display) { + Emit("display-removed"); +} + +void Screen::OnDisplayMetricsChanged(const gfx::Display& display, + uint32_t changed_metrics) { + Emit("display-metrics-changed"); +} + +mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return mate::ObjectTemplateBuilder(isolate) + .SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint) + .SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay) + .SetMethod("getAllDisplays", &Screen::GetAllDisplays) + .SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint) + .SetMethod("getDisplayMatching", &Screen::GetDisplayMatching); +} + +// static +mate::Handle Screen::Create(v8::Isolate* isolate) { + gfx::Screen* screen = gfx::Screen::GetNativeScreen(); + if (!screen) { + isolate->ThrowException(v8::Exception::Error(mate::StringToV8( + isolate, "Failed to get screen information"))); + return mate::Handle(); + } + + return CreateHandle(isolate, new Screen(screen)); +} + +} // namespace api + +} // namespace atom + namespace { void Initialize(v8::Handle exports, v8::Handle unused, v8::Handle context, void* priv) { - auto screen = base::Unretained(gfx::Screen::GetNativeScreen()); mate::Dictionary dict(context->GetIsolate(), exports); - dict.SetMethod("getCursorScreenPoint", - base::Bind(&gfx::Screen::GetCursorScreenPoint, screen)); - dict.SetMethod("getPrimaryDisplay", - base::Bind(&gfx::Screen::GetPrimaryDisplay, screen)); - dict.SetMethod("getAllDisplays", - base::Bind(&gfx::Screen::GetAllDisplays, screen)); - dict.SetMethod("getDisplayNearestPoint", - base::Bind(&gfx::Screen::GetDisplayNearestPoint, screen)); - dict.SetMethod("getDisplayMatching", - base::Bind(&gfx::Screen::GetDisplayMatching, screen)); + dict.Set("screen", atom::api::Screen::Create(context->GetIsolate())); } } // namespace diff --git a/atom/browser/api/atom_api_screen.h b/atom/browser/api/atom_api_screen.h new file mode 100644 index 000000000000..ff5095666abd --- /dev/null +++ b/atom/browser/api/atom_api_screen.h @@ -0,0 +1,59 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_API_ATOM_API_SCREEN_H_ +#define ATOM_BROWSER_API_ATOM_API_SCREEN_H_ + +#include + +#include "atom/browser/api/event_emitter.h" +#include "native_mate/handle.h" +#include "ui/gfx/display_observer.h" + +namespace gfx { +class Point; +class Rect; +class Screen; +} + +namespace atom { + +namespace api { + +class Screen : public mate::EventEmitter, + public gfx::DisplayObserver { + public: + static mate::Handle Create(v8::Isolate* isolate); + + protected: + explicit Screen(gfx::Screen* screen); + virtual ~Screen(); + + gfx::Point GetCursorScreenPoint(); + gfx::Display GetPrimaryDisplay(); + std::vector GetAllDisplays(); + gfx::Display GetDisplayNearestPoint(const gfx::Point& point); + gfx::Display GetDisplayMatching(const gfx::Rect& match_rect); + + // gfx::DisplayObserver: + void OnDisplayAdded(const gfx::Display& new_display) override; + void OnDisplayRemoved(const gfx::Display& old_display) override; + void OnDisplayMetricsChanged(const gfx::Display& display, + uint32_t changed_metrics) override; + + // mate::Wrappable: + mate::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override; + + private: + gfx::Screen* screen_; + + DISALLOW_COPY_AND_ASSIGN(Screen); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_API_SCREEN_H_ diff --git a/atom/browser/api/lib/screen.coffee b/atom/browser/api/lib/screen.coffee index 0e1e229ca614..6ef5a5f66338 100644 --- a/atom/browser/api/lib/screen.coffee +++ b/atom/browser/api/lib/screen.coffee @@ -1,11 +1,6 @@ -binding = process.atomBinding 'screen' +EventEmitter = require('events').EventEmitter -checkAppIsReady = -> - unless process.type is 'renderer' or require('app').isReady() - throw new Error('Can not use screen module before the "ready" event of app module gets emitted') +screen = process.atomBinding('screen').screen +screen.__proto__ = EventEmitter.prototype -for name, _ of binding - do (name) -> - module.exports[name] = (args...) -> - checkAppIsReady() - binding[name](args...) +module.exports = screen