From 322bde526c2698df8b4678c89d412fd43a49fdd8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 22 May 2018 17:08:27 +0900 Subject: [PATCH 1/3] Add LayoutManager/BoxLayout APIs --- atom/browser/api/atom_api_box_layout.cc | 77 +++++++++++++++++++ atom/browser/api/atom_api_box_layout.h | 35 +++++++++ atom/browser/api/atom_api_browser_window.cc | 13 +--- atom/browser/api/atom_api_layout_manager.cc | 63 +++++++++++++++ atom/browser/api/atom_api_layout_manager.h | 44 +++++++++++ atom/browser/api/atom_api_view.cc | 13 +++- atom/browser/api/atom_api_view.h | 7 +- .../browser/api/atom_api_web_contents_view.cc | 9 +-- atom/common/api/constructor.h | 33 ++++++++ atom/common/node_bindings.cc | 2 + filenames.gypi | 7 ++ lib/browser/api/box-layout.js | 15 ++++ lib/browser/api/layout-manager.js | 8 ++ lib/browser/api/module-list.js | 2 + 14 files changed, 310 insertions(+), 18 deletions(-) create mode 100644 atom/browser/api/atom_api_box_layout.cc create mode 100644 atom/browser/api/atom_api_box_layout.h create mode 100644 atom/browser/api/atom_api_layout_manager.cc create mode 100644 atom/browser/api/atom_api_layout_manager.h create mode 100644 atom/common/api/constructor.h create mode 100644 lib/browser/api/box-layout.js create mode 100644 lib/browser/api/layout-manager.js diff --git a/atom/browser/api/atom_api_box_layout.cc b/atom/browser/api/atom_api_box_layout.cc new file mode 100644 index 000000000000..b37430b6eb0d --- /dev/null +++ b/atom/browser/api/atom_api_box_layout.cc @@ -0,0 +1,77 @@ +// Copyright (c) 2018 GitHub, Inc. +// 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_box_layout.h" + +#include + +#include "atom/common/api/constructor.h" +#include "native_mate/dictionary.h" + +#include "atom/common/node_includes.h" + +namespace mate { + +template <> +struct Converter { + static bool FromV8(v8::Isolate* isolate, + v8::Handle val, + views::BoxLayout::Orientation* out) { + std::string orientation; + if (!ConvertFromV8(isolate, val, &orientation)) + return false; + if (orientation == "horizontal") + *out = views::BoxLayout::kHorizontal; + else if (orientation == "vertical") + *out = views::BoxLayout::kVertical; + else + return false; + return true; + } +}; + +} // namespace mate + +namespace atom { + +namespace api { + +BoxLayout::BoxLayout(views::BoxLayout::Orientation orientation) + : LayoutManager(new views::BoxLayout(orientation)) {} + +BoxLayout::~BoxLayout() {} + +// static +mate::WrappableBase* BoxLayout::New(mate::Arguments* args, + views::BoxLayout::Orientation orientation) { + auto* layout = new BoxLayout(orientation); + layout->InitWith(args->isolate(), args->GetThis()); + return layout; +} + +// static +void BoxLayout::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) {} + +} // namespace api + +} // namespace atom + +namespace { + +using atom::api::BoxLayout; + +void Initialize(v8::Local exports, + v8::Local unused, + v8::Local context, + void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + mate::Dictionary dict(isolate, exports); + dict.Set("BoxLayout", mate::CreateConstructor( + isolate, base::Bind(&BoxLayout::New))); +} + +} // namespace + +NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_box_layout, Initialize) diff --git a/atom/browser/api/atom_api_box_layout.h b/atom/browser/api/atom_api_box_layout.h new file mode 100644 index 000000000000..804cc244c1d4 --- /dev/null +++ b/atom/browser/api/atom_api_box_layout.h @@ -0,0 +1,35 @@ +// Copyright (c) 2018 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_BOX_LAYOUT_H_ +#define ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_ + +#include "atom/browser/api/atom_api_layout_manager.h" +#include "ui/views/layout/box_layout.h" + +namespace atom { + +namespace api { + +class BoxLayout : public LayoutManager { + public: + static mate::WrappableBase* New(mate::Arguments* args, + views::BoxLayout::Orientation orientation); + + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + + protected: + explicit BoxLayout(views::BoxLayout::Orientation orientation); + ~BoxLayout() override; + + private: + DISALLOW_COPY_AND_ASSIGN(BoxLayout); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_ diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index ce85e52d4370..a987828be55b 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -9,6 +9,7 @@ #include "atom/browser/web_contents_preferences.h" #include "atom/browser/window_list.h" #include "atom/common/api/api_messages.h" +#include "atom/common/api/constructor.h" #include "atom/common/color_util.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/value_converter.h" @@ -428,17 +429,9 @@ void Initialize(v8::Local exports, v8::Local context, void* priv) { v8::Isolate* isolate = context->GetIsolate(); - // Calling SetConstructor would only use TopLevelWindow's prototype. - v8::Local templ = CreateFunctionTemplate( - isolate, - base::Bind( - &mate::internal::InvokeNew, - base::Bind(&BrowserWindow::New))); - templ->InstanceTemplate()->SetInternalFieldCount(1); - BrowserWindow::BuildPrototype(isolate, templ); - mate::Dictionary dict(isolate, exports); - dict.Set("BrowserWindow", templ->GetFunction()); + dict.Set("BrowserWindow", mate::CreateConstructor( + isolate, base::Bind(&BrowserWindow::New))); } } // namespace diff --git a/atom/browser/api/atom_api_layout_manager.cc b/atom/browser/api/atom_api_layout_manager.cc new file mode 100644 index 000000000000..49c8cea5e748 --- /dev/null +++ b/atom/browser/api/atom_api_layout_manager.cc @@ -0,0 +1,63 @@ +// Copyright (c) 2018 GitHub, Inc. +// 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_layout_manager.h" + +#include "atom/common/api/constructor.h" +#include "native_mate/dictionary.h" + +#include "atom/common/node_includes.h" + +namespace atom { + +namespace api { + +LayoutManager::LayoutManager(views::LayoutManager* layout_manager) + : layout_manager_(layout_manager) { + DCHECK(layout_manager_); +} + +LayoutManager::~LayoutManager() { + if (managed_by_us_) + delete layout_manager_; +} + +std::unique_ptr LayoutManager::TakeOver() { + if (!managed_by_us_) // already taken over. + return nullptr; + managed_by_us_ = false; + return std::unique_ptr(layout_manager_); +} + +// static +mate::WrappableBase* LayoutManager::New(mate::Arguments* args) { + args->ThrowError("LayoutManager can not be created directly"); + return nullptr; +} + +// static +void LayoutManager::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) {} + +} // namespace api + +} // namespace atom + +namespace { + +using atom::api::LayoutManager; + +void Initialize(v8::Local exports, + v8::Local unused, + v8::Local context, + void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + mate::Dictionary dict(isolate, exports); + dict.Set("LayoutManager", mate::CreateConstructor( + isolate, base::Bind(&LayoutManager::New))); +} + +} // namespace + +NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_layout_manager, Initialize) diff --git a/atom/browser/api/atom_api_layout_manager.h b/atom/browser/api/atom_api_layout_manager.h new file mode 100644 index 000000000000..4e893b746b80 --- /dev/null +++ b/atom/browser/api/atom_api_layout_manager.h @@ -0,0 +1,44 @@ +// Copyright (c) 2018 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_LAYOUT_MANAGER_H_ +#define ATOM_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_ + +#include + +#include "atom/browser/api/trackable_object.h" +#include "ui/views/layout/layout_manager.h" + +namespace atom { + +namespace api { + +class LayoutManager : public mate::TrackableObject { + public: + static mate::WrappableBase* New(mate::Arguments* args); + + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + + // Take over the ownership of the LayoutManager, and leave weak ref here. + std::unique_ptr TakeOver(); + + views::LayoutManager* layout_manager() const { return layout_manager_; } + + protected: + explicit LayoutManager(views::LayoutManager* layout_manager); + ~LayoutManager() override; + + private: + bool managed_by_us_ = true; + views::LayoutManager* layout_manager_; + + DISALLOW_COPY_AND_ASSIGN(LayoutManager); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_ diff --git a/atom/browser/api/atom_api_view.cc b/atom/browser/api/atom_api_view.cc index 07db4bfca17a..650ad18cdecd 100644 --- a/atom/browser/api/atom_api_view.cc +++ b/atom/browser/api/atom_api_view.cc @@ -23,6 +23,13 @@ View::~View() { delete view_; } +void View::SetLayoutManager(mate::Handle layout_manager) { + layout_manager_.Reset(isolate(), layout_manager->GetWrapper()); + // TODO(zcbenz): New versions of Chrome takes std::unique_ptr instead of raw + // pointer, remove the "release()" call when we upgraded to it. + view()->SetLayoutManager(layout_manager->TakeOver().release()); +} + // static mate::WrappableBase* View::New(mate::Arguments* args) { auto* view = new View(); @@ -32,7 +39,11 @@ mate::WrappableBase* View::New(mate::Arguments* args) { // static void View::BuildPrototype(v8::Isolate* isolate, - v8::Local prototype) {} + v8::Local prototype) { + prototype->SetClassName(mate::StringToV8(isolate, "View")); + mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) + .SetMethod("setLayoutManager", &View::SetLayoutManager); +} } // namespace api diff --git a/atom/browser/api/atom_api_view.h b/atom/browser/api/atom_api_view.h index 4e851ef28983..37f7ae4e1c73 100644 --- a/atom/browser/api/atom_api_view.h +++ b/atom/browser/api/atom_api_view.h @@ -7,7 +7,8 @@ #include -#include "atom/browser/api/trackable_object.h" +#include "atom/browser/api/atom_api_layout_manager.h" +#include "native_mate/handle.h" #include "ui/views/view.h" namespace atom { @@ -21,6 +22,8 @@ class View : public mate::TrackableObject { static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); + void SetLayoutManager(mate::Handle layout_manager); + views::View* view() const { return view_; } protected: @@ -32,6 +35,8 @@ class View : public mate::TrackableObject { void set_delete_view(bool should) { delete_view_ = should; } private: + v8::Global layout_manager_; + bool delete_view_ = true; views::View* view_ = nullptr; diff --git a/atom/browser/api/atom_api_web_contents_view.cc b/atom/browser/api/atom_api_web_contents_view.cc index de27f8eeed64..60d04ff936ba 100644 --- a/atom/browser/api/atom_api_web_contents_view.cc +++ b/atom/browser/api/atom_api_web_contents_view.cc @@ -5,6 +5,7 @@ #include "atom/browser/api/atom_api_web_contents_view.h" #include "atom/browser/api/atom_api_web_contents.h" +#include "atom/common/api/constructor.h" #include "brightray/browser/inspectable_web_contents_view.h" #include "content/public/browser/web_contents_user_data.h" #include "native_mate/dictionary.h" @@ -117,13 +118,9 @@ void Initialize(v8::Local exports, v8::Local context, void* priv) { v8::Isolate* isolate = context->GetIsolate(); - WebContentsView::SetConstructor(isolate, base::Bind(&WebContentsView::New)); - - mate::Dictionary constructor( - isolate, WebContentsView::GetConstructor(isolate)->GetFunction()); - mate::Dictionary dict(isolate, exports); - dict.Set("WebContentsView", constructor); + dict.Set("WebContentsView", mate::CreateConstructor( + isolate, base::Bind(&WebContentsView::New))); } } // namespace diff --git a/atom/common/api/constructor.h b/atom/common/api/constructor.h new file mode 100644 index 000000000000..a4e4332f0a55 --- /dev/null +++ b/atom/common/api/constructor.h @@ -0,0 +1,33 @@ +// Copyright (c) 2018 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_API_CONSTRUCTOR_H_ +#define ATOM_COMMON_API_CONSTRUCTOR_H_ + +#include "native_mate/constructor.h" + +namespace mate { + +// Create a FunctionTemplate that can be "new"ed in JavaScript. +// It is user's responsibility to ensure this function is called for one type +// only ONCE in the program's whole lifetime, otherwise we would have memory +// leak. +template +v8::Local CreateConstructor(v8::Isolate* isolate, + const base::Callback& func) { +#ifndef NDEBUG + static bool called = false; + CHECK(!called) << "CreateConstructor can only be called for one type once"; + called = true; +#endif + v8::Local templ = CreateFunctionTemplate( + isolate, base::Bind(&mate::internal::InvokeNew, func)); + templ->InstanceTemplate()->SetInternalFieldCount(1); + T::BuildPrototype(isolate, templ); + return templ->GetFunction(); +} + +} // namespace mate + +#endif // ATOM_COMMON_API_CONSTRUCTOR_H_ diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index d50327934c8d..8af9114de8fc 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -31,6 +31,7 @@ V(atom_browser_app) \ V(atom_browser_auto_updater) \ V(atom_browser_browser_view) \ + V(atom_browser_box_layout) \ V(atom_browser_content_tracing) \ V(atom_browser_debugger) \ V(atom_browser_desktop_capturer) \ @@ -38,6 +39,7 @@ V(atom_browser_download_item) \ V(atom_browser_global_shortcut) \ V(atom_browser_in_app_purchase) \ + V(atom_browser_layout_manager) \ V(atom_browser_menu) \ V(atom_browser_net) \ V(atom_browser_power_monitor) \ diff --git a/filenames.gypi b/filenames.gypi index ec0c59f0a020..9da6d9cdff13 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -13,6 +13,7 @@ 'lib/browser/api/auto-updater/auto-updater-native.js', 'lib/browser/api/auto-updater/auto-updater-win.js', 'lib/browser/api/auto-updater/squirrel-update-win.js', + 'lib/browser/api/box-layout.js', 'lib/browser/api/browser-view.js', 'lib/browser/api/browser-window.js', 'lib/browser/api/content-tracing.js', @@ -21,6 +22,7 @@ 'lib/browser/api/global-shortcut.js', 'lib/browser/api/ipc-main.js', 'lib/browser/api/in-app-purchase.js', + 'lib/browser/api/layout-manager.js', 'lib/browser/api/menu-item-roles.js', 'lib/browser/api/menu-item.js', 'lib/browser/api/menu-utils.js', @@ -113,6 +115,8 @@ 'atom/browser/api/atom_api_app.h', 'atom/browser/api/atom_api_auto_updater.cc', 'atom/browser/api/atom_api_auto_updater.h', + 'atom/browser/api/atom_api_box_layout.cc', + 'atom/browser/api/atom_api_box_layout.h', 'atom/browser/api/atom_api_browser_view.cc', 'atom/browser/api/atom_api_browser_view.h', 'atom/browser/api/atom_api_content_tracing.cc', @@ -129,6 +133,8 @@ 'atom/browser/api/atom_api_global_shortcut.h', 'atom/browser/api/atom_api_in_app_purchase.cc', 'atom/browser/api/atom_api_in_app_purchase.h', + 'atom/browser/api/atom_api_layout_manager.cc', + 'atom/browser/api/atom_api_layout_manager.h', 'atom/browser/api/atom_api_menu.cc', 'atom/browser/api/atom_api_menu.h', 'atom/browser/api/atom_api_menu_mac.h', @@ -436,6 +442,7 @@ 'atom/common/api/atom_api_v8_util.cc', 'atom/common/api/atom_bindings.cc', 'atom/common/api/atom_bindings.h', + 'atom/common/api/constructor.h', 'atom/common/api/event_emitter_caller.cc', 'atom/common/api/event_emitter_caller.h', 'atom/common/api/features.cc', diff --git a/lib/browser/api/box-layout.js b/lib/browser/api/box-layout.js new file mode 100644 index 000000000000..4dc77f319407 --- /dev/null +++ b/lib/browser/api/box-layout.js @@ -0,0 +1,15 @@ +'use strict' + +const electron = require('electron') + +const {LayoutManager} = electron +const {BoxLayout} = process.atomBinding('box_layout') + +Object.setPrototypeOf(BoxLayout.prototype, LayoutManager.prototype) + +BoxLayout.prototype._init = function () { + // Call parent class's _init. + LayoutManager.prototype._init.call(this) +} + +module.exports = BoxLayout diff --git a/lib/browser/api/layout-manager.js b/lib/browser/api/layout-manager.js new file mode 100644 index 000000000000..1a850a53450e --- /dev/null +++ b/lib/browser/api/layout-manager.js @@ -0,0 +1,8 @@ +'use strict' + +const {LayoutManager} = process.atomBinding('layout_manager') + +LayoutManager.prototype._init = function () { +} + +module.exports = LayoutManager diff --git a/lib/browser/api/module-list.js b/lib/browser/api/module-list.js index 5b218838acf9..663da97c3e6f 100644 --- a/lib/browser/api/module-list.js +++ b/lib/browser/api/module-list.js @@ -2,6 +2,7 @@ module.exports = [ {name: 'app', file: 'app'}, {name: 'autoUpdater', file: 'auto-updater'}, + {name: 'BoxLayout', file: 'box-layout'}, {name: 'BrowserView', file: 'browser-view'}, {name: 'BrowserWindow', file: 'browser-window'}, {name: 'contentTracing', file: 'content-tracing'}, @@ -9,6 +10,7 @@ module.exports = [ {name: 'globalShortcut', file: 'global-shortcut'}, {name: 'ipcMain', file: 'ipc-main'}, {name: 'inAppPurchase', file: 'in-app-purchase'}, + {name: 'LayoutManager', file: 'layout-manager'}, {name: 'Menu', file: 'menu'}, {name: 'MenuItem', file: 'menu-item'}, {name: 'net', file: 'net'}, From 2c8dc9e0bd68d246216950b8ecec1f9bd30a5776 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 23 May 2018 13:30:57 +0900 Subject: [PATCH 2/3] Add View.addChildView API --- atom/browser/api/atom_api_box_layout.cc | 12 +++++++++++- atom/browser/api/atom_api_box_layout.h | 5 +++++ atom/browser/api/atom_api_view.cc | 16 +++++++++++++++- atom/browser/api/atom_api_view.h | 4 ++++ .../browser/ui/cocoa/delayed_native_view_host.cc | 2 +- 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_box_layout.cc b/atom/browser/api/atom_api_box_layout.cc index b37430b6eb0d..99e2efc55b75 100644 --- a/atom/browser/api/atom_api_box_layout.cc +++ b/atom/browser/api/atom_api_box_layout.cc @@ -6,6 +6,7 @@ #include +#include "atom/browser/api/atom_api_view.h" #include "atom/common/api/constructor.h" #include "native_mate/dictionary.h" @@ -42,6 +43,11 @@ BoxLayout::BoxLayout(views::BoxLayout::Orientation orientation) BoxLayout::~BoxLayout() {} +void BoxLayout::SetFlexForView(mate::Handle view, int flex) { + auto* box_layout = static_cast(layout_manager()); + box_layout->SetFlexForView(view->view(), flex); +} + // static mate::WrappableBase* BoxLayout::New(mate::Arguments* args, views::BoxLayout::Orientation orientation) { @@ -52,7 +58,11 @@ mate::WrappableBase* BoxLayout::New(mate::Arguments* args, // static void BoxLayout::BuildPrototype(v8::Isolate* isolate, - v8::Local prototype) {} + v8::Local prototype) { + prototype->SetClassName(mate::StringToV8(isolate, "BoxLayout")); + mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) + .SetMethod("setFlexForView", &BoxLayout::SetFlexForView); +} } // namespace api diff --git a/atom/browser/api/atom_api_box_layout.h b/atom/browser/api/atom_api_box_layout.h index 804cc244c1d4..b29e2eda6ab0 100644 --- a/atom/browser/api/atom_api_box_layout.h +++ b/atom/browser/api/atom_api_box_layout.h @@ -6,12 +6,15 @@ #define ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_ #include "atom/browser/api/atom_api_layout_manager.h" +#include "native_mate/handle.h" #include "ui/views/layout/box_layout.h" namespace atom { namespace api { +class View; + class BoxLayout : public LayoutManager { public: static mate::WrappableBase* New(mate::Arguments* args, @@ -20,6 +23,8 @@ class BoxLayout : public LayoutManager { static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); + void SetFlexForView(mate::Handle view, int flex); + protected: explicit BoxLayout(views::BoxLayout::Orientation orientation); ~BoxLayout() override; diff --git a/atom/browser/api/atom_api_view.cc b/atom/browser/api/atom_api_view.cc index 650ad18cdecd..a79e6fa689d9 100644 --- a/atom/browser/api/atom_api_view.cc +++ b/atom/browser/api/atom_api_view.cc @@ -30,6 +30,18 @@ void View::SetLayoutManager(mate::Handle layout_manager) { view()->SetLayoutManager(layout_manager->TakeOver().release()); } +void View::AddChildView(mate::Handle child) { + AddChildViewAt(child, child_views_.size()); +} + +void View::AddChildViewAt(mate::Handle child, size_t index) { + if (index > child_views_.size()) + return; + child_views_.emplace(child_views_.begin() + index, // index + isolate(), child->GetWrapper()); // v8::Global(args...) + view()->AddChildViewAt(child->view(), index); +} + // static mate::WrappableBase* View::New(mate::Arguments* args) { auto* view = new View(); @@ -42,7 +54,9 @@ void View::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { prototype->SetClassName(mate::StringToV8(isolate, "View")); mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) - .SetMethod("setLayoutManager", &View::SetLayoutManager); + .SetMethod("setLayoutManager", &View::SetLayoutManager) + .SetMethod("addChildView", &View::AddChildView) + .SetMethod("addChildViewAt", &View::AddChildViewAt); } } // namespace api diff --git a/atom/browser/api/atom_api_view.h b/atom/browser/api/atom_api_view.h index 37f7ae4e1c73..80f17e614167 100644 --- a/atom/browser/api/atom_api_view.h +++ b/atom/browser/api/atom_api_view.h @@ -6,6 +6,7 @@ #define ATOM_BROWSER_API_ATOM_API_VIEW_H_ #include +#include #include "atom/browser/api/atom_api_layout_manager.h" #include "native_mate/handle.h" @@ -23,6 +24,8 @@ class View : public mate::TrackableObject { v8::Local prototype); void SetLayoutManager(mate::Handle layout_manager); + void AddChildView(mate::Handle view); + void AddChildViewAt(mate::Handle view, size_t index); views::View* view() const { return view_; } @@ -36,6 +39,7 @@ class View : public mate::TrackableObject { private: v8::Global layout_manager_; + std::vector> child_views_; bool delete_view_ = true; views::View* view_ = nullptr; diff --git a/atom/browser/ui/cocoa/delayed_native_view_host.cc b/atom/browser/ui/cocoa/delayed_native_view_host.cc index 0d48668895d0..95d369bfd82c 100644 --- a/atom/browser/ui/cocoa/delayed_native_view_host.cc +++ b/atom/browser/ui/cocoa/delayed_native_view_host.cc @@ -14,7 +14,7 @@ DelayedNativeViewHost::~DelayedNativeViewHost() {} void DelayedNativeViewHost::ViewHierarchyChanged( const ViewHierarchyChangedDetails& details) { NativeViewHost::ViewHierarchyChanged(details); - if (details.is_add) + if (details.is_add && GetWidget()) Attach(native_view_); } From 0f7c25fc63887b276d40af08050d329d23f8a99f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 24 May 2018 15:35:50 +0900 Subject: [PATCH 3/3] Put View APIs under a build flag --- atom/browser/api/atom_api_view.cc | 4 ++++ atom/browser/api/atom_api_view.h | 2 ++ atom/common/node_bindings.cc | 12 ++++++++++-- electron.gyp | 5 +++++ features.gypi | 2 ++ filenames.gypi | 18 ++++++++++++------ 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_view.cc b/atom/browser/api/atom_api_view.cc index a79e6fa689d9..9094fd5476bb 100644 --- a/atom/browser/api/atom_api_view.cc +++ b/atom/browser/api/atom_api_view.cc @@ -23,6 +23,7 @@ View::~View() { delete view_; } +#if defined(ENABLE_VIEW_API) void View::SetLayoutManager(mate::Handle layout_manager) { layout_manager_.Reset(isolate(), layout_manager->GetWrapper()); // TODO(zcbenz): New versions of Chrome takes std::unique_ptr instead of raw @@ -41,6 +42,7 @@ void View::AddChildViewAt(mate::Handle child, size_t index) { isolate(), child->GetWrapper()); // v8::Global(args...) view()->AddChildViewAt(child->view(), index); } +#endif // static mate::WrappableBase* View::New(mate::Arguments* args) { @@ -53,10 +55,12 @@ mate::WrappableBase* View::New(mate::Arguments* args) { void View::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { prototype->SetClassName(mate::StringToV8(isolate, "View")); +#if defined(ENABLE_VIEW_API) mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) .SetMethod("setLayoutManager", &View::SetLayoutManager) .SetMethod("addChildView", &View::AddChildView) .SetMethod("addChildViewAt", &View::AddChildViewAt); +#endif } } // namespace api diff --git a/atom/browser/api/atom_api_view.h b/atom/browser/api/atom_api_view.h index 80f17e614167..03b4e10823c9 100644 --- a/atom/browser/api/atom_api_view.h +++ b/atom/browser/api/atom_api_view.h @@ -23,9 +23,11 @@ class View : public mate::TrackableObject { static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); +#if defined(ENABLE_VIEW_API) void SetLayoutManager(mate::Handle layout_manager); void AddChildView(mate::Handle view); void AddChildViewAt(mate::Handle view, size_t index); +#endif views::View* view() const { return view_; } diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 8af9114de8fc..e939de070865 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -31,7 +31,6 @@ V(atom_browser_app) \ V(atom_browser_auto_updater) \ V(atom_browser_browser_view) \ - V(atom_browser_box_layout) \ V(atom_browser_content_tracing) \ V(atom_browser_debugger) \ V(atom_browser_desktop_capturer) \ @@ -39,7 +38,6 @@ V(atom_browser_download_item) \ V(atom_browser_global_shortcut) \ V(atom_browser_in_app_purchase) \ - V(atom_browser_layout_manager) \ V(atom_browser_menu) \ V(atom_browser_net) \ V(atom_browser_power_monitor) \ @@ -67,6 +65,10 @@ V(atom_renderer_ipc) \ V(atom_renderer_web_frame) +#define ELECTRON_VIEW_MODULES(V) \ + V(atom_browser_box_layout) \ + V(atom_browser_layout_manager) + // This is used to load built-in modules. Instead of using // __attribute__((constructor)), we call the _register_ // function for each built-in modules explicitly. This is only @@ -74,6 +76,9 @@ // implementation when calling the NODE_BUILTIN_MODULE_CONTEXT_AWARE. #define V(modname) void _register_##modname(); ELECTRON_BUILTIN_MODULES(V) +#if defined(ENABLE_VIEW_API) +ELECTRON_VIEW_MODULES(V) +#endif #undef V namespace { @@ -167,6 +172,9 @@ NodeBindings::~NodeBindings() { void NodeBindings::RegisterBuiltinModules() { #define V(modname) _register_##modname(); ELECTRON_BUILTIN_MODULES(V) +#if defined(ENABLE_VIEW_API) + ELECTRON_VIEW_MODULES(V) +#endif #undef V } diff --git a/electron.gyp b/electron.gyp index fec9239e480e..b040ee1ab876 100644 --- a/electron.gyp +++ b/electron.gyp @@ -38,6 +38,11 @@ 'ENABLE_RUN_AS_NODE', ], }], # enable_run_as_node + ['enable_view_api==1', { + 'defines': [ + 'ENABLE_VIEW_API', + ], + }], # enable_view_api ], }, 'targets': [ diff --git a/features.gypi b/features.gypi index 247d828bbc01..b3dca5da2ca0 100644 --- a/features.gypi +++ b/features.gypi @@ -5,9 +5,11 @@ 'enable_osr%': 1, # FIXME(alexeykuzmin) 'enable_pdf_viewer%': 0, # FIXME(deepak1556) 'enable_run_as_node%': 1, + 'enable_view_api%': 0, }, 'enable_osr%': '<(enable_osr)', 'enable_pdf_viewer%': '<(enable_pdf_viewer)', 'enable_run_as_node%': '<(enable_run_as_node)', + 'enable_view_api%': '<(enable_view_api)', }, } diff --git a/filenames.gypi b/filenames.gypi index 9da6d9cdff13..4cecf4b896a3 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -13,7 +13,6 @@ 'lib/browser/api/auto-updater/auto-updater-native.js', 'lib/browser/api/auto-updater/auto-updater-win.js', 'lib/browser/api/auto-updater/squirrel-update-win.js', - 'lib/browser/api/box-layout.js', 'lib/browser/api/browser-view.js', 'lib/browser/api/browser-window.js', 'lib/browser/api/content-tracing.js', @@ -22,7 +21,6 @@ 'lib/browser/api/global-shortcut.js', 'lib/browser/api/ipc-main.js', 'lib/browser/api/in-app-purchase.js', - 'lib/browser/api/layout-manager.js', 'lib/browser/api/menu-item-roles.js', 'lib/browser/api/menu-item.js', 'lib/browser/api/menu-utils.js', @@ -115,8 +113,6 @@ 'atom/browser/api/atom_api_app.h', 'atom/browser/api/atom_api_auto_updater.cc', 'atom/browser/api/atom_api_auto_updater.h', - 'atom/browser/api/atom_api_box_layout.cc', - 'atom/browser/api/atom_api_box_layout.h', 'atom/browser/api/atom_api_browser_view.cc', 'atom/browser/api/atom_api_browser_view.h', 'atom/browser/api/atom_api_content_tracing.cc', @@ -133,8 +129,6 @@ 'atom/browser/api/atom_api_global_shortcut.h', 'atom/browser/api/atom_api_in_app_purchase.cc', 'atom/browser/api/atom_api_in_app_purchase.h', - 'atom/browser/api/atom_api_layout_manager.cc', - 'atom/browser/api/atom_api_layout_manager.h', 'atom/browser/api/atom_api_menu.cc', 'atom/browser/api/atom_api_menu.h', 'atom/browser/api/atom_api_menu_mac.h', @@ -781,6 +775,18 @@ 'atom/app/node_main.h', ], }], # enable_run_as_node + ['enable_view_api==1', { + 'js_sources': [ + 'lib/browser/api/box-layout.js', + 'lib/browser/api/layout-manager.js', + ], + 'lib_sources': [ + 'atom/browser/api/atom_api_box_layout.cc', + 'atom/browser/api/atom_api_box_layout.h', + 'atom/browser/api/atom_api_layout_manager.cc', + 'atom/browser/api/atom_api_layout_manager.h', + ], + }], # enable_view_api ['mas_build==1', { 'lib_sources': [ 'atom/browser/api/atom_api_app_mas.mm',