From 858828d34388372bf2ea2a633523056914d687f8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 14 Apr 2018 11:04:23 +0900 Subject: [PATCH] Refactor NativeWindow (Part 6): Move NativeWindow bindings to api::TopLevelWindow (#12596) * Add atom::api::TopLevelWindow * Make BrowserWindow inherit TopLevelWindow * Fix reading from wrong weak map * Read options after setting content view * OnWindowClosed is not guarenteed to run now * Fix the offscreen hack in BrowserWindow * Fix building on Linux * Fix tests on Linux * Fix building on Windows --- atom/browser/api/atom_api_browser_window.cc | 1131 ++--------------- atom/browser/api/atom_api_browser_window.h | 234 +--- atom/browser/api/atom_api_menu_mac.mm | 3 +- atom/browser/api/atom_api_menu_views.cc | 2 +- atom/browser/api/atom_api_top_level_window.cc | 1057 +++++++++++++++ atom/browser/api/atom_api_top_level_window.h | 226 ++++ atom/browser/api/atom_api_web_contents.cc | 1 + atom/browser/api/trackable_object.h | 5 +- atom/common/node_bindings.cc | 1 + filenames.gypi | 2 + 10 files changed, 1406 insertions(+), 1256 deletions(-) create mode 100644 atom/browser/api/atom_api_top_level_window.cc create mode 100644 atom/browser/api/atom_api_top_level_window.h diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index 7a5ec7de18f7..83234f0ca34f 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -4,88 +4,33 @@ #include "atom/browser/api/atom_api_browser_window.h" -#include "atom/browser/api/atom_api_browser_view.h" -#include "atom/browser/api/atom_api_menu.h" -#include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/browser.h" -#include "atom/browser/native_window.h" #include "atom/browser/unresponsive_suppressor.h" #include "atom/browser/web_contents_preferences.h" #include "atom/browser/window_list.h" #include "atom/common/api/api_messages.h" #include "atom/common/color_util.h" #include "atom/common/native_mate_converters/callback.h" -#include "atom/common/native_mate_converters/file_path_converter.h" -#include "atom/common/native_mate_converters/gfx_converter.h" -#include "atom/common/native_mate_converters/gurl_converter.h" -#include "atom/common/native_mate_converters/image_converter.h" -#include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/options_switches.h" -#include "base/command_line.h" #include "base/threading/thread_task_runner_handle.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" -#include "content/public/common/content_switches.h" -#include "native_mate/constructor.h" #include "native_mate/dictionary.h" -#include "ui/gfx/geometry/rect.h" #include "ui/gl/gpu_switching_manager.h" -#if defined(TOOLKIT_VIEWS) -#include "atom/browser/native_window_views.h" -#endif - -#if defined(OS_WIN) -#include "atom/browser/ui/win/taskbar_host.h" -#include "ui/base/win/shell.h" -#endif - #include "atom/common/node_includes.h" -#if defined(OS_WIN) -namespace mate { - -template<> -struct Converter { - static bool FromV8(v8::Isolate* isolate, v8::Handle val, - atom::TaskbarHost::ThumbarButton* out) { - mate::Dictionary dict; - if (!ConvertFromV8(isolate, val, &dict)) - return false; - dict.Get("click", &(out->clicked_callback)); - dict.Get("tooltip", &(out->tooltip)); - dict.Get("flags", &out->flags); - return dict.Get("icon", &(out->icon)); - } -}; - -} // namespace mate -#endif - namespace atom { namespace api { -namespace { - -// Converts binary data to Buffer. -v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { - auto buffer = node::Buffer::Copy(isolate, static_cast(val), size); - if (buffer.IsEmpty()) - return v8::Null(isolate); - else - return buffer.ToLocalChecked(); -} - -} // namespace - - BrowserWindow::BrowserWindow(v8::Isolate* isolate, v8::Local wrapper, const mate::Dictionary& options) - : weak_factory_(this) { + : TopLevelWindow(isolate, wrapper, options), + weak_factory_(this) { mate::Handle web_contents; // Use options.webPreferences in WebContents. @@ -101,15 +46,6 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate, if (options.Get("transparent", &transparent)) web_preferences.Set("transparent", transparent); -#if defined(ENABLE_OSR) - // Offscreen windows are always created frameless. - bool offscreen; - if (web_preferences.Get("offscreen", &offscreen) && offscreen) { - auto window_options = const_cast(options); - window_options.Set(options::kFrame, false); - } -#endif - if (options.Get("webContents", &web_contents) && !web_contents.IsEmpty()) { // Set webPreferences from options if using an existing webContents. // These preferences will be used when the webContent launches new @@ -127,13 +63,6 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate, web_contents = WebContents::Create(isolate, web_preferences); } - Init(isolate, wrapper, options, web_contents); -} - -void BrowserWindow::Init(v8::Isolate* isolate, - v8::Local wrapper, - const mate::Dictionary& options, - mate::Handle web_contents) { web_contents_.Reset(isolate, web_contents.ToV8()); api_web_contents_ = web_contents.get(); api_web_contents_->AddObserver(this); @@ -143,54 +72,30 @@ void BrowserWindow::Init(v8::Isolate* isolate, mate::Dictionary(isolate, web_contents->GetWrapper()).Set( "browserWindowOptions", options); - // The parent window. - mate::Handle parent; - if (options.Get("parent", &parent) && !parent.IsEmpty()) - parent_window_.Reset(isolate, parent.ToV8()); - - // Creates BrowserWindow. - window_.reset(NativeWindow::Create( - options, - parent.IsEmpty() ? nullptr : parent->window_.get())); - window_->SetContentView(web_contents->managed_web_contents()); - web_contents->SetOwnerWindow(window_.get()); - // Tell the content module to initialize renderer widget with transparent // mode. - ui::GpuSwitchingManager::SetTransparent(window_->transparent()); + ui::GpuSwitchingManager::SetTransparent(window()->transparent()); -#if defined(TOOLKIT_VIEWS) - // Sets the window icon. - mate::Handle icon; - if (options.Get(options::kIcon, &icon) && !icon.IsEmpty()) - SetIcon(icon); -#endif - - window_->InitFromOptions(options); - window_->AddObserver(this); - - InitWith(isolate, wrapper); - AttachAsUserData(window_.get()); - - // We can only append this window to parent window's child windows after this - // window's JS wrapper gets initialized. - if (!parent.IsEmpty()) - parent->child_windows_.Set(isolate, ID(), wrapper); + // Associate with BrowserWindow. + web_contents->SetOwnerWindow(window()); + window()->SetContentView(web_contents->managed_web_contents()); auto* host = web_contents->web_contents()->GetRenderViewHost(); if (host) host->GetWidget()->AddInputEventObserver(this); + + InitWith(isolate, wrapper); + + // Init window after everything has been setup. + window()->InitFromOptions(options); } BrowserWindow::~BrowserWindow() { - if (!window_->IsClosed()) - window_->CloseImmediately(); - api_web_contents_->RemoveObserver(this); - - // Destroy the native window in next tick because the native code might be - // iterating all windows. - base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release()); + // Note that the OnWindowClosed will not be called after the destructor runs, + // since the window object is managed by the TopLevelWindow class. + if (web_contents()) + Cleanup(); } void BrowserWindow::OnInputEvent(const blink::WebInputEvent& event) { @@ -215,7 +120,7 @@ void BrowserWindow::RenderViewHostChanged(content::RenderViewHost* old_host, void BrowserWindow::RenderViewCreated( content::RenderViewHost* render_view_host) { - if (!window_->transparent()) + if (!window()->transparent()) return; content::RenderWidgetHostImpl* impl = content::RenderWidgetHostImpl::FromID( @@ -226,14 +131,14 @@ void BrowserWindow::RenderViewCreated( } void BrowserWindow::DidFirstVisuallyNonEmptyPaint() { - if (window_->IsVisible()) + if (window()->IsVisible()) return; // When there is a non-empty first paint, resize the RenderWidget to force // Chromium to draw. const auto view = web_contents()->GetRenderWidgetHostView(); view->Show(); - view->SetSize(window_->GetContentSize()); + view->SetSize(window()->GetContentSize()); // Emit the ReadyToShow event in next tick in case of pending drawing work. base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -245,7 +150,7 @@ void BrowserWindow::DidFirstVisuallyNonEmptyPaint() { } void BrowserWindow::BeforeUnloadDialogCancelled() { - WindowList::WindowCloseCancelled(window_.get()); + WindowList::WindowCloseCancelled(window()); // Cancel unresponsive event when window close is cancelled. window_unresponsive_closure_.Cancel(); } @@ -281,7 +186,7 @@ void BrowserWindow::OnCloseContents() { for (v8::Local value : child_windows_.Values(isolate())) { mate::Handle child; if (mate::ConvertFromV8(isolate(), value, &child) && !child.IsEmpty()) - child->window_->CloseImmediately(); + child->window()->CloseImmediately(); } // When the web contents is gone, close the window immediately, but the @@ -289,7 +194,7 @@ void BrowserWindow::OnCloseContents() { // In this way, it would be safe to manage windows via smart pointers. If you // want to free memory when the window is closed, you can do deleting by // overriding the OnWindowClosed method in the observer. - window_->CloseImmediately(); + window()->CloseImmediately(); // Do not sent "unresponsive" event after window is closed. window_unresponsive_closure_.Cancel(); @@ -300,10 +205,6 @@ void BrowserWindow::OnRendererResponsive() { Emit("responsive"); } -void BrowserWindow::WillCloseWindow(bool* prevent_default) { - *prevent_default = Emit("close"); -} - void BrowserWindow::RequestPreferredWidth(int* width) { *width = web_contents()->GetPreferredSize().width(); } @@ -332,33 +233,8 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) { } void BrowserWindow::OnWindowClosed() { - auto* host = web_contents()->GetRenderViewHost(); - if (host) - host->GetWidget()->RemoveInputEventObserver(this); - - api_web_contents_->DestroyWebContents(true /* async */); - - Observe(nullptr); - RemoveFromWeakMap(); - window_->RemoveObserver(this); - - // We can not call Destroy here because we need to call Emit first, but we - // also do not want any method to be used, so just mark as destroyed here. - MarkDestroyed(); - - Emit("closed"); - - RemoveFromParentChildWindows(); - - ResetBrowserView(); - - // Destroy the native class when window is closed. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, GetDestroyClosure()); -} - -void BrowserWindow::OnWindowEndSession() { - Emit("session-end"); + Cleanup(); + TopLevelWindow::OnWindowClosed(); } void BrowserWindow::OnWindowBlur() { @@ -369,7 +245,7 @@ void BrowserWindow::OnWindowBlur() { rwhv->SetActive(false); #endif - Emit("blur"); + TopLevelWindow::OnWindowBlur(); } void BrowserWindow::OnWindowFocus() { @@ -383,31 +259,7 @@ void BrowserWindow::OnWindowFocus() { web_contents()->Focus(); #endif - Emit("focus"); -} - -void BrowserWindow::OnWindowShow() { - Emit("show"); -} - -void BrowserWindow::OnWindowHide() { - Emit("hide"); -} - -void BrowserWindow::OnWindowMaximize() { - Emit("maximize"); -} - -void BrowserWindow::OnWindowUnmaximize() { - Emit("unmaximize"); -} - -void BrowserWindow::OnWindowMinimize() { - Emit("minimize"); -} - -void BrowserWindow::OnWindowRestore() { - Emit("restore"); + TopLevelWindow::OnWindowFocus(); } void BrowserWindow::OnWindowResize() { @@ -415,728 +267,35 @@ void BrowserWindow::OnWindowResize() { if (!draggable_regions_.empty()) UpdateDraggableRegions(nullptr, draggable_regions_); #endif - Emit("resize"); -} - -void BrowserWindow::OnWindowMove() { - Emit("move"); -} - -void BrowserWindow::OnWindowMoved() { - Emit("moved"); -} - -void BrowserWindow::OnWindowEnterFullScreen() { - Emit("enter-full-screen"); -} - -void BrowserWindow::OnWindowLeaveFullScreen() { - Emit("leave-full-screen"); -} - -void BrowserWindow::OnWindowScrollTouchBegin() { - Emit("scroll-touch-begin"); -} - -void BrowserWindow::OnWindowScrollTouchEnd() { - Emit("scroll-touch-end"); -} - -void BrowserWindow::OnWindowSwipe(const std::string& direction) { - Emit("swipe", direction); -} - -void BrowserWindow::OnWindowSheetBegin() { - Emit("sheet-begin"); -} - -void BrowserWindow::OnWindowSheetEnd() { - Emit("sheet-end"); -} - -void BrowserWindow::OnWindowEnterHtmlFullScreen() { - Emit("enter-html-full-screen"); -} - -void BrowserWindow::OnWindowLeaveHtmlFullScreen() { - Emit("leave-html-full-screen"); -} - -void BrowserWindow::OnExecuteWindowsCommand(const std::string& command_name) { - Emit("app-command", command_name); -} - -void BrowserWindow::OnTouchBarItemResult(const std::string& item_id, - const base::DictionaryValue& details) { - Emit("-touch-bar-interaction", item_id, details); -} - -void BrowserWindow::OnNewWindowForTab() { - Emit("new-window-for-tab"); -} - -#if defined(OS_WIN) -void BrowserWindow::OnWindowMessage(UINT message, - WPARAM w_param, - LPARAM l_param) { - if (IsWindowMessageHooked(message)) { - messages_callback_map_[message].Run( - ToBuffer(isolate(), static_cast(&w_param), sizeof(WPARAM)), - ToBuffer(isolate(), static_cast(&l_param), sizeof(LPARAM))); - } -} -#endif - -// static -mate::WrappableBase* BrowserWindow::New(mate::Arguments* args) { - if (!Browser::Get()->is_ready()) { - args->ThrowError("Cannot create BrowserWindow before app is ready"); - return nullptr; - } - - if (args->Length() > 1) { - args->ThrowError(); - return nullptr; - } - - mate::Dictionary options; - if (!(args->Length() == 1 && args->GetNext(&options))) { - options = mate::Dictionary::CreateEmpty(args->isolate()); - } - - return new BrowserWindow(args->isolate(), args->GetThis(), options); -} - -void BrowserWindow::Close() { - window_->Close(); + TopLevelWindow::OnWindowResize(); } void BrowserWindow::Focus() { - if (api_web_contents_->IsOffScreen()) { + if (api_web_contents_->IsOffScreen()) FocusOnWebView(); - } else { - window_->Focus(true); - } + else + TopLevelWindow::Focus(); } void BrowserWindow::Blur() { - if (api_web_contents_->IsOffScreen()) { + if (api_web_contents_->IsOffScreen()) BlurWebView(); - } else { - window_->Focus(false); - } -} - -bool BrowserWindow::IsFocused() { - return window_->IsFocused(); -} - -void BrowserWindow::Show() { - window_->Show(); -} - -void BrowserWindow::ShowInactive() { - // This method doesn't make sense for modal window.. - if (IsModal()) - return; - - window_->ShowInactive(); -} - -void BrowserWindow::Hide() { - window_->Hide(); -} - -bool BrowserWindow::IsVisible() { - return window_->IsVisible(); -} - -bool BrowserWindow::IsEnabled() { - return window_->IsEnabled(); -} - -void BrowserWindow::SetEnabled(bool enable) { - window_->SetEnabled(enable); -} - -void BrowserWindow::Maximize() { - window_->Maximize(); -} - -void BrowserWindow::Unmaximize() { - window_->Unmaximize(); -} - -bool BrowserWindow::IsMaximized() { - return window_->IsMaximized(); -} - -void BrowserWindow::Minimize() { - window_->Minimize(); -} - -void BrowserWindow::Restore() { - window_->Restore(); -} - -bool BrowserWindow::IsMinimized() { - return window_->IsMinimized(); -} - -void BrowserWindow::SetFullScreen(bool fullscreen) { - window_->SetFullScreen(fullscreen); -} - -bool BrowserWindow::IsFullscreen() { - return window_->IsFullscreen(); -} - -void BrowserWindow::SetBounds(const gfx::Rect& bounds, mate::Arguments* args) { - bool animate = false; - args->GetNext(&animate); - window_->SetBounds(bounds, animate); -} - -gfx::Rect BrowserWindow::GetBounds() { - return window_->GetBounds(); -} - -void BrowserWindow::SetContentBounds(const gfx::Rect& bounds, - mate::Arguments* args) { - bool animate = false; - args->GetNext(&animate); - window_->SetContentBounds(bounds, animate); -} - -gfx::Rect BrowserWindow::GetContentBounds() { - return window_->GetContentBounds(); -} - -void BrowserWindow::SetSize(int width, int height, mate::Arguments* args) { - bool animate = false; - args->GetNext(&animate); - window_->SetSize(gfx::Size(width, height), animate); -} - -std::vector BrowserWindow::GetSize() { - std::vector result(2); - gfx::Size size = window_->GetSize(); - result[0] = size.width(); - result[1] = size.height(); - return result; -} - -void BrowserWindow::SetContentSize(int width, int height, - mate::Arguments* args) { - bool animate = false; - args->GetNext(&animate); - window_->SetContentSize(gfx::Size(width, height), animate); -} - -std::vector BrowserWindow::GetContentSize() { - std::vector result(2); - gfx::Size size = window_->GetContentSize(); - result[0] = size.width(); - result[1] = size.height(); - return result; -} - -void BrowserWindow::SetMinimumSize(int width, int height) { - window_->SetMinimumSize(gfx::Size(width, height)); -} - -std::vector BrowserWindow::GetMinimumSize() { - std::vector result(2); - gfx::Size size = window_->GetMinimumSize(); - result[0] = size.width(); - result[1] = size.height(); - return result; -} - -void BrowserWindow::SetMaximumSize(int width, int height) { - window_->SetMaximumSize(gfx::Size(width, height)); -} - -std::vector BrowserWindow::GetMaximumSize() { - std::vector result(2); - gfx::Size size = window_->GetMaximumSize(); - result[0] = size.width(); - result[1] = size.height(); - return result; -} - -void BrowserWindow::SetSheetOffset(double offsetY, mate::Arguments* args) { - double offsetX = 0.0; - args->GetNext(&offsetX); - window_->SetSheetOffset(offsetX, offsetY); -} - -void BrowserWindow::SetResizable(bool resizable) { - window_->SetResizable(resizable); -} - -bool BrowserWindow::IsResizable() { - return window_->IsResizable(); -} - -void BrowserWindow::SetMovable(bool movable) { - window_->SetMovable(movable); -} - -bool BrowserWindow::IsMovable() { - return window_->IsMovable(); -} - -void BrowserWindow::SetMinimizable(bool minimizable) { - window_->SetMinimizable(minimizable); -} - -bool BrowserWindow::IsMinimizable() { - return window_->IsMinimizable(); -} - -void BrowserWindow::SetMaximizable(bool maximizable) { - window_->SetMaximizable(maximizable); -} - -bool BrowserWindow::IsMaximizable() { - return window_->IsMaximizable(); -} - -void BrowserWindow::SetFullScreenable(bool fullscreenable) { - window_->SetFullScreenable(fullscreenable); -} - -bool BrowserWindow::IsFullScreenable() { - return window_->IsFullScreenable(); -} - -void BrowserWindow::SetClosable(bool closable) { - window_->SetClosable(closable); -} - -bool BrowserWindow::IsClosable() { - return window_->IsClosable(); -} - -void BrowserWindow::SetAlwaysOnTop(bool top, mate::Arguments* args) { - std::string level = "floating"; - int relativeLevel = 0; - std::string error; - - args->GetNext(&level); - args->GetNext(&relativeLevel); - - window_->SetAlwaysOnTop(top, level, relativeLevel, &error); - - if (!error.empty()) { - args->ThrowError(error); - } -} - -bool BrowserWindow::IsAlwaysOnTop() { - return window_->IsAlwaysOnTop(); -} - -void BrowserWindow::Center() { - window_->Center(); -} - -void BrowserWindow::SetPosition(int x, int y, mate::Arguments* args) { - bool animate = false; - args->GetNext(&animate); - window_->SetPosition(gfx::Point(x, y), animate); -} - -std::vector BrowserWindow::GetPosition() { - std::vector result(2); - gfx::Point pos = window_->GetPosition(); - result[0] = pos.x(); - result[1] = pos.y(); - return result; -} - -#if defined(OS_WIN) || defined(OS_MACOSX) -void BrowserWindow::MoveTop() { - window_->MoveTop(); -} -#endif - -void BrowserWindow::SetTitle(const std::string& title) { - window_->SetTitle(title); -} - -std::string BrowserWindow::GetTitle() { - return window_->GetTitle(); -} - -void BrowserWindow::FlashFrame(bool flash) { - window_->FlashFrame(flash); -} - -void BrowserWindow::SetSkipTaskbar(bool skip) { - window_->SetSkipTaskbar(skip); -} - -void BrowserWindow::SetSimpleFullScreen(bool simple_fullscreen) { - window_->SetSimpleFullScreen(simple_fullscreen); -} - -bool BrowserWindow::IsSimpleFullScreen() { - return window_->IsSimpleFullScreen(); -} - -void BrowserWindow::SetKiosk(bool kiosk) { - window_->SetKiosk(kiosk); -} - -bool BrowserWindow::IsKiosk() { - return window_->IsKiosk(); + else + TopLevelWindow::Blur(); } void BrowserWindow::SetBackgroundColor(const std::string& color_name) { - SkColor color = ParseHexColor(color_name); - window_->SetBackgroundColor(color); + TopLevelWindow::SetBackgroundColor(color_name); auto* view = web_contents()->GetRenderWidgetHostView(); if (view) - view->SetBackgroundColor(color); -} - -void BrowserWindow::SetHasShadow(bool has_shadow) { - window_->SetHasShadow(has_shadow); -} - -bool BrowserWindow::HasShadow() { - return window_->HasShadow(); -} - -void BrowserWindow::SetOpacity(const double opacity) { - window_->SetOpacity(opacity); -} - -double BrowserWindow::GetOpacity() { - return window_->GetOpacity(); -} - -void BrowserWindow::FocusOnWebView() { - web_contents()->GetRenderViewHost()->GetWidget()->Focus(); -} - -void BrowserWindow::BlurWebView() { - web_contents()->GetRenderViewHost()->GetWidget()->Blur(); -} - -bool BrowserWindow::IsWebViewFocused() { - auto host_view = web_contents()->GetRenderViewHost()->GetWidget()->GetView(); - return host_view && host_view->HasFocus(); -} - -void BrowserWindow::SetRepresentedFilename(const std::string& filename) { - window_->SetRepresentedFilename(filename); -} - -std::string BrowserWindow::GetRepresentedFilename() { - return window_->GetRepresentedFilename(); -} - -void BrowserWindow::SetDocumentEdited(bool edited) { - window_->SetDocumentEdited(edited); -} - -bool BrowserWindow::IsDocumentEdited() { - return window_->IsDocumentEdited(); -} - -void BrowserWindow::SetIgnoreMouseEvents(bool ignore, mate::Arguments* args) { - mate::Dictionary options; - bool forward = false; - args->GetNext(&options) && options.Get("forward", &forward); - return window_->SetIgnoreMouseEvents(ignore, forward); -} - -void BrowserWindow::SetContentProtection(bool enable) { - return window_->SetContentProtection(enable); -} - -void BrowserWindow::SetFocusable(bool focusable) { - return window_->SetFocusable(focusable); -} - -void BrowserWindow::SetProgressBar(double progress, mate::Arguments* args) { - mate::Dictionary options; - std::string mode; - NativeWindow::ProgressState state = NativeWindow::PROGRESS_NORMAL; - - args->GetNext(&options) && options.Get("mode", &mode); - - if (mode == "error") { - state = NativeWindow::PROGRESS_ERROR; - } else if (mode == "paused") { - state = NativeWindow::PROGRESS_PAUSED; - } else if (mode == "indeterminate") { - state = NativeWindow::PROGRESS_INDETERMINATE; - } else if (mode == "none") { - state = NativeWindow::PROGRESS_NONE; - } - - window_->SetProgressBar(progress, state); -} - -void BrowserWindow::SetOverlayIcon(const gfx::Image& overlay, - const std::string& description) { - window_->SetOverlayIcon(overlay, description); -} - -bool BrowserWindow::SetThumbarButtons(mate::Arguments* args) { -#if defined(OS_WIN) - std::vector buttons; - if (!args->GetNext(&buttons)) { - args->ThrowError(); - return false; - } - auto window = static_cast(window_.get()); - return window->taskbar_host().SetThumbarButtons( - window_->GetAcceleratedWidget(), buttons); -#else - return false; -#endif -} - -void BrowserWindow::SetMenu(v8::Isolate* isolate, v8::Local value) { - mate::Handle menu; - if (value->IsObject() && - mate::V8ToString(value->ToObject()->GetConstructorName()) == "Menu" && - mate::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) { - menu_.Reset(isolate, menu.ToV8()); - window_->SetMenu(menu->model()); - } else if (value->IsNull()) { - menu_.Reset(); - window_->SetMenu(nullptr); - } else { - isolate->ThrowException(v8::Exception::TypeError( - mate::StringToV8(isolate, "Invalid Menu"))); - } -} - -void BrowserWindow::SetAutoHideMenuBar(bool auto_hide) { - window_->SetAutoHideMenuBar(auto_hide); -} - -bool BrowserWindow::IsMenuBarAutoHide() { - return window_->IsMenuBarAutoHide(); -} - -void BrowserWindow::SetMenuBarVisibility(bool visible) { - window_->SetMenuBarVisibility(visible); -} - -bool BrowserWindow::IsMenuBarVisible() { - return window_->IsMenuBarVisible(); -} - -#if defined(OS_WIN) -bool BrowserWindow::HookWindowMessage(UINT message, - const MessageCallback& callback) { - messages_callback_map_[message] = callback; - return true; -} - -void BrowserWindow::UnhookWindowMessage(UINT message) { - if (!ContainsKey(messages_callback_map_, message)) - return; - - messages_callback_map_.erase(message); -} - -bool BrowserWindow::IsWindowMessageHooked(UINT message) { - return ContainsKey(messages_callback_map_, message); -} - -void BrowserWindow::UnhookAllWindowMessages() { - messages_callback_map_.clear(); -} - -bool BrowserWindow::SetThumbnailClip(const gfx::Rect& region) { - auto window = static_cast(window_.get()); - return window->taskbar_host().SetThumbnailClip( - window_->GetAcceleratedWidget(), region); -} - -bool BrowserWindow::SetThumbnailToolTip(const std::string& tooltip) { - auto window = static_cast(window_.get()); - return window->taskbar_host().SetThumbnailToolTip( - window_->GetAcceleratedWidget(), tooltip); -} - -void BrowserWindow::SetAppDetails(const mate::Dictionary& options) { - base::string16 app_id; - base::FilePath app_icon_path; - int app_icon_index = 0; - base::string16 relaunch_command; - base::string16 relaunch_display_name; - - options.Get("appId", &app_id); - options.Get("appIconPath", &app_icon_path); - options.Get("appIconIndex", &app_icon_index); - options.Get("relaunchCommand", &relaunch_command); - options.Get("relaunchDisplayName", &relaunch_display_name); - - ui::win::SetAppDetailsForWindow( - app_id, app_icon_path, app_icon_index, - relaunch_command, relaunch_display_name, - window_->GetAcceleratedWidget()); -} -#endif - -#if defined(TOOLKIT_VIEWS) -void BrowserWindow::SetIcon(mate::Handle icon) { -#if defined(OS_WIN) - static_cast(window_.get())->SetIcon( - icon->GetHICON(GetSystemMetrics(SM_CXSMICON)), - icon->GetHICON(GetSystemMetrics(SM_CXICON))); -#elif defined(USE_X11) - static_cast(window_.get())->SetIcon( - icon->image().AsImageSkia()); -#endif -} -#endif - -void BrowserWindow::SetAspectRatio(double aspect_ratio, mate::Arguments* args) { - gfx::Size extra_size; - args->GetNext(&extra_size); - window_->SetAspectRatio(aspect_ratio, extra_size); -} - -void BrowserWindow::PreviewFile(const std::string& path, - mate::Arguments* args) { - std::string display_name; - if (!args->GetNext(&display_name)) - display_name = path; - window_->PreviewFile(path, display_name); -} - -void BrowserWindow::CloseFilePreview() { - window_->CloseFilePreview(); -} - -void BrowserWindow::SetParentWindow(v8::Local value, - mate::Arguments* args) { - if (IsModal()) { - args->ThrowError("Can not be called for modal window"); - return; - } - - mate::Handle parent; - if (value->IsNull() || value->IsUndefined()) { - RemoveFromParentChildWindows(); - parent_window_.Reset(); - window_->SetParentWindow(nullptr); - } else if (mate::ConvertFromV8(isolate(), value, &parent)) { - parent_window_.Reset(isolate(), value); - window_->SetParentWindow(parent->window_.get()); - parent->child_windows_.Set(isolate(), ID(), GetWrapper()); - } else { - args->ThrowError("Must pass BrowserWindow instance or null"); - } -} - -v8::Local BrowserWindow::GetParentWindow() const { - if (parent_window_.IsEmpty()) - return v8::Null(isolate()); - else - return v8::Local::New(isolate(), parent_window_); -} - -std::vector> BrowserWindow::GetChildWindows() const { - return child_windows_.Values(isolate()); -} - -v8::Local BrowserWindow::GetBrowserView() const { - if (browser_view_.IsEmpty()) { - return v8::Null(isolate()); - } - - return v8::Local::New(isolate(), browser_view_); + view->SetBackgroundColor(ParseHexColor(color_name)); } void BrowserWindow::SetBrowserView(v8::Local value) { - ResetBrowserView(); - - mate::Handle browser_view; - if (value->IsNull() || value->IsUndefined()) { - window_->SetBrowserView(nullptr); - } else if (mate::ConvertFromV8(isolate(), value, &browser_view)) { - window_->SetBrowserView(browser_view->view()); - browser_view->web_contents()->SetOwnerWindow(window_.get()); - browser_view_.Reset(isolate(), value); - + TopLevelWindow::SetBrowserView(value); #if defined(OS_MACOSX) - UpdateDraggableRegions(nullptr, draggable_regions_); + UpdateDraggableRegions(nullptr, draggable_regions_); #endif - } -} - -void BrowserWindow::ResetBrowserView() { - if (browser_view_.IsEmpty()) { - return; - } - - mate::Handle browser_view; - if (mate::ConvertFromV8(isolate(), GetBrowserView(), &browser_view) - && !browser_view.IsEmpty()) { - browser_view->web_contents()->SetOwnerWindow(nullptr); - } - - browser_view_.Reset(); -} - -bool BrowserWindow::IsModal() const { - return window_->is_modal(); -} - -v8::Local BrowserWindow::GetNativeWindowHandle() { - gfx::AcceleratedWidget handle = window_->GetAcceleratedWidget(); - return ToBuffer( - isolate(), static_cast(&handle), sizeof(gfx::AcceleratedWidget)); -} - -void BrowserWindow::SetVisibleOnAllWorkspaces(bool visible) { - return window_->SetVisibleOnAllWorkspaces(visible); -} - -bool BrowserWindow::IsVisibleOnAllWorkspaces() { - return window_->IsVisibleOnAllWorkspaces(); -} - -void BrowserWindow::SetAutoHideCursor(bool auto_hide) { - window_->SetAutoHideCursor(auto_hide); -} - -void BrowserWindow::SelectPreviousTab() { - window_->SelectPreviousTab(); -} - -void BrowserWindow::SelectNextTab() { - window_->SelectNextTab(); -} - -void BrowserWindow::MergeAllWindows() { - window_->MergeAllWindows(); -} - -void BrowserWindow::MoveTabToNewWindow() { - window_->MoveTabToNewWindow(); -} - -void BrowserWindow::ToggleTabBar() { - window_->ToggleTabBar(); -} - -void BrowserWindow::AddTabbedWindow(NativeWindow* window, - mate::Arguments* args) { - const bool windowAdded = window_->AddTabbedWindow(window); - if (!windowAdded) - args->ThrowError("AddTabbedWindow cannot be called by a window on itself."); } void BrowserWindow::SetVibrancy(mate::Arguments* args) { @@ -1152,48 +311,28 @@ void BrowserWindow::SetVibrancy(mate::Arguments* args) { impl->SetBackgroundOpaque(type.empty() ? !window_->transparent() : false); } - window_->SetVibrancy(type); + TopLevelWindow::SetVibrancy(args); } -void BrowserWindow::SetTouchBar( - const std::vector& items) { - window_->SetTouchBar(items); +void BrowserWindow::FocusOnWebView() { + web_contents()->GetRenderViewHost()->GetWidget()->Focus(); } -void BrowserWindow::RefreshTouchBarItem(const std::string& item_id) { - window_->RefreshTouchBarItem(item_id); +void BrowserWindow::BlurWebView() { + web_contents()->GetRenderViewHost()->GetWidget()->Blur(); } -void BrowserWindow::SetEscapeTouchBarItem( - const mate::PersistentDictionary& item) { - window_->SetEscapeTouchBarItem(item); +bool BrowserWindow::IsWebViewFocused() { + auto host_view = web_contents()->GetRenderViewHost()->GetWidget()->GetView(); + return host_view && host_view->HasFocus(); } -int32_t BrowserWindow::ID() const { - return weak_map_id(); -} - -v8::Local BrowserWindow::WebContents(v8::Isolate* isolate) { - if (web_contents_.IsEmpty()) { +v8::Local BrowserWindow::GetWebContents(v8::Isolate* isolate) { + if (web_contents_.IsEmpty()) return v8::Null(isolate); - } - return v8::Local::New(isolate, web_contents_); } -void BrowserWindow::RemoveFromParentChildWindows() { - if (parent_window_.IsEmpty()) - return; - - mate::Handle parent; - if (!mate::ConvertFromV8(isolate(), GetParentWindow(), &parent) - || parent.IsEmpty()) { - return; - } - - parent->child_windows_.Remove(ID()); -} - // Convert draggable regions in raw format to SkRegion format. std::unique_ptr BrowserWindow::DraggableRegionsToSkRegion( const std::vector& regions) { @@ -1229,142 +368,46 @@ void BrowserWindow::NotifyWindowUnresponsive() { } } +void BrowserWindow::Cleanup() { + auto* host = web_contents()->GetRenderViewHost(); + if (host) + host->GetWidget()->RemoveInputEventObserver(this); + + api_web_contents_->DestroyWebContents(true /* async */); + Observe(nullptr); +} + +// static +mate::WrappableBase* BrowserWindow::New(mate::Arguments* args) { + if (!Browser::Get()->is_ready()) { + args->ThrowError("Cannot create BrowserWindow before app is ready"); + return nullptr; + } + + if (args->Length() > 1) { + args->ThrowError(); + return nullptr; + } + + mate::Dictionary options; + if (!(args->Length() == 1 && args->GetNext(&options))) { + options = mate::Dictionary::CreateEmpty(args->isolate()); + } + + return new BrowserWindow(args->isolate(), args->GetThis(), options); +} + + // static void BrowserWindow::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { + TopLevelWindow::BuildPrototype(isolate, prototype); prototype->SetClassName(mate::StringToV8(isolate, "BrowserWindow")); mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) - .MakeDestroyable() - .SetMethod("close", &BrowserWindow::Close) - .SetMethod("focus", &BrowserWindow::Focus) - .SetMethod("blur", &BrowserWindow::Blur) - .SetMethod("isFocused", &BrowserWindow::IsFocused) - .SetMethod("show", &BrowserWindow::Show) - .SetMethod("showInactive", &BrowserWindow::ShowInactive) - .SetMethod("hide", &BrowserWindow::Hide) - .SetMethod("isVisible", &BrowserWindow::IsVisible) - .SetMethod("isEnabled", &BrowserWindow::IsEnabled) - .SetMethod("setEnabled", & BrowserWindow::SetEnabled) - .SetMethod("maximize", &BrowserWindow::Maximize) - .SetMethod("unmaximize", &BrowserWindow::Unmaximize) - .SetMethod("isMaximized", &BrowserWindow::IsMaximized) - .SetMethod("minimize", &BrowserWindow::Minimize) - .SetMethod("restore", &BrowserWindow::Restore) - .SetMethod("isMinimized", &BrowserWindow::IsMinimized) - .SetMethod("setFullScreen", &BrowserWindow::SetFullScreen) - .SetMethod("isFullScreen", &BrowserWindow::IsFullscreen) - .SetMethod("setAspectRatio", &BrowserWindow::SetAspectRatio) - .SetMethod("previewFile", &BrowserWindow::PreviewFile) - .SetMethod("closeFilePreview", &BrowserWindow::CloseFilePreview) -#if !defined(OS_WIN) - .SetMethod("setParentWindow", &BrowserWindow::SetParentWindow) -#endif - .SetMethod("getParentWindow", &BrowserWindow::GetParentWindow) - .SetMethod("getChildWindows", &BrowserWindow::GetChildWindows) - .SetMethod("getBrowserView", &BrowserWindow::GetBrowserView) - .SetMethod("setBrowserView", &BrowserWindow::SetBrowserView) - .SetMethod("isModal", &BrowserWindow::IsModal) - .SetMethod("getNativeWindowHandle", &BrowserWindow::GetNativeWindowHandle) - .SetMethod("getBounds", &BrowserWindow::GetBounds) - .SetMethod("setBounds", &BrowserWindow::SetBounds) - .SetMethod("getSize", &BrowserWindow::GetSize) - .SetMethod("setSize", &BrowserWindow::SetSize) - .SetMethod("getContentBounds", &BrowserWindow::GetContentBounds) - .SetMethod("setContentBounds", &BrowserWindow::SetContentBounds) - .SetMethod("getContentSize", &BrowserWindow::GetContentSize) - .SetMethod("setContentSize", &BrowserWindow::SetContentSize) - .SetMethod("setMinimumSize", &BrowserWindow::SetMinimumSize) - .SetMethod("getMinimumSize", &BrowserWindow::GetMinimumSize) - .SetMethod("setMaximumSize", &BrowserWindow::SetMaximumSize) - .SetMethod("getMaximumSize", &BrowserWindow::GetMaximumSize) - .SetMethod("setSheetOffset", &BrowserWindow::SetSheetOffset) - .SetMethod("setResizable", &BrowserWindow::SetResizable) - .SetMethod("isResizable", &BrowserWindow::IsResizable) - .SetMethod("setMovable", &BrowserWindow::SetMovable) - .SetMethod("isMovable", &BrowserWindow::IsMovable) - .SetMethod("setMinimizable", &BrowserWindow::SetMinimizable) - .SetMethod("isMinimizable", &BrowserWindow::IsMinimizable) - .SetMethod("setMaximizable", &BrowserWindow::SetMaximizable) - .SetMethod("isMaximizable", &BrowserWindow::IsMaximizable) - .SetMethod("setFullScreenable", &BrowserWindow::SetFullScreenable) - .SetMethod("isFullScreenable", &BrowserWindow::IsFullScreenable) - .SetMethod("setClosable", &BrowserWindow::SetClosable) - .SetMethod("isClosable", &BrowserWindow::IsClosable) - .SetMethod("setAlwaysOnTop", &BrowserWindow::SetAlwaysOnTop) - .SetMethod("isAlwaysOnTop", &BrowserWindow::IsAlwaysOnTop) - .SetMethod("center", &BrowserWindow::Center) - .SetMethod("setPosition", &BrowserWindow::SetPosition) - .SetMethod("getPosition", &BrowserWindow::GetPosition) -#if defined(OS_WIN) || defined(OS_MACOSX) - .SetMethod("moveTop" , &BrowserWindow::MoveTop) -#endif - .SetMethod("setTitle", &BrowserWindow::SetTitle) - .SetMethod("getTitle", &BrowserWindow::GetTitle) - .SetMethod("flashFrame", &BrowserWindow::FlashFrame) - .SetMethod("setSkipTaskbar", &BrowserWindow::SetSkipTaskbar) - .SetMethod("setSimpleFullScreen", &BrowserWindow::SetSimpleFullScreen) - .SetMethod("isSimpleFullScreen", &BrowserWindow::IsSimpleFullScreen) - .SetMethod("setKiosk", &BrowserWindow::SetKiosk) - .SetMethod("isKiosk", &BrowserWindow::IsKiosk) - .SetMethod("setBackgroundColor", &BrowserWindow::SetBackgroundColor) - .SetMethod("setHasShadow", &BrowserWindow::SetHasShadow) - .SetMethod("hasShadow", &BrowserWindow::HasShadow) - .SetMethod("setOpacity", &BrowserWindow::SetOpacity) - .SetMethod("getOpacity", &BrowserWindow::GetOpacity) - .SetMethod("setRepresentedFilename", - &BrowserWindow::SetRepresentedFilename) - .SetMethod("getRepresentedFilename", - &BrowserWindow::GetRepresentedFilename) - .SetMethod("setDocumentEdited", &BrowserWindow::SetDocumentEdited) - .SetMethod("isDocumentEdited", &BrowserWindow::IsDocumentEdited) - .SetMethod("setIgnoreMouseEvents", &BrowserWindow::SetIgnoreMouseEvents) - .SetMethod("setContentProtection", &BrowserWindow::SetContentProtection) - .SetMethod("setFocusable", &BrowserWindow::SetFocusable) .SetMethod("focusOnWebView", &BrowserWindow::FocusOnWebView) .SetMethod("blurWebView", &BrowserWindow::BlurWebView) .SetMethod("isWebViewFocused", &BrowserWindow::IsWebViewFocused) - .SetMethod("setProgressBar", &BrowserWindow::SetProgressBar) - .SetMethod("setOverlayIcon", &BrowserWindow::SetOverlayIcon) - .SetMethod("setThumbarButtons", &BrowserWindow::SetThumbarButtons) - .SetMethod("setMenu", &BrowserWindow::SetMenu) - .SetMethod("setAutoHideMenuBar", &BrowserWindow::SetAutoHideMenuBar) - .SetMethod("isMenuBarAutoHide", &BrowserWindow::IsMenuBarAutoHide) - .SetMethod("setMenuBarVisibility", &BrowserWindow::SetMenuBarVisibility) - .SetMethod("isMenuBarVisible", &BrowserWindow::IsMenuBarVisible) - .SetMethod("setVisibleOnAllWorkspaces", - &BrowserWindow::SetVisibleOnAllWorkspaces) - .SetMethod("isVisibleOnAllWorkspaces", - &BrowserWindow::IsVisibleOnAllWorkspaces) -#if defined(OS_MACOSX) - .SetMethod("setAutoHideCursor", &BrowserWindow::SetAutoHideCursor) - .SetMethod("mergeAllWindows", &BrowserWindow::MergeAllWindows) - .SetMethod("selectPreviousTab", &BrowserWindow::SelectPreviousTab) - .SetMethod("selectNextTab", &BrowserWindow::SelectNextTab) - .SetMethod("moveTabToNewWindow", &BrowserWindow::MoveTabToNewWindow) - .SetMethod("toggleTabBar", &BrowserWindow::ToggleTabBar) - .SetMethod("addTabbedWindow", &BrowserWindow::AddTabbedWindow) -#endif - .SetMethod("setVibrancy", &BrowserWindow::SetVibrancy) - .SetMethod("_setTouchBarItems", &BrowserWindow::SetTouchBar) - .SetMethod("_refreshTouchBarItem", &BrowserWindow::RefreshTouchBarItem) - .SetMethod("_setEscapeTouchBarItem", - &BrowserWindow::SetEscapeTouchBarItem) -#if defined(OS_WIN) - .SetMethod("hookWindowMessage", &BrowserWindow::HookWindowMessage) - .SetMethod("isWindowMessageHooked", - &BrowserWindow::IsWindowMessageHooked) - .SetMethod("unhookWindowMessage", &BrowserWindow::UnhookWindowMessage) - .SetMethod("unhookAllWindowMessages", - &BrowserWindow::UnhookAllWindowMessages) - .SetMethod("setThumbnailClip", &BrowserWindow::SetThumbnailClip) - .SetMethod("setThumbnailToolTip", &BrowserWindow::SetThumbnailToolTip) - .SetMethod("setAppDetails", &BrowserWindow::SetAppDetails) -#endif -#if defined(TOOLKIT_VIEWS) - .SetMethod("setIcon", &BrowserWindow::SetIcon) -#endif - .SetProperty("id", &BrowserWindow::ID) - .SetProperty("webContents", &BrowserWindow::WebContents); + .SetProperty("webContents", &BrowserWindow::GetWebContents); } // static @@ -1381,24 +424,30 @@ v8::Local BrowserWindow::From(v8::Isolate* isolate, } // namespace atom - namespace { using atom::api::BrowserWindow; +using atom::api::TopLevelWindow; void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { v8::Isolate* isolate = context->GetIsolate(); - BrowserWindow::SetConstructor(isolate, base::Bind(&BrowserWindow::New)); + // 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 browser_window( - isolate, BrowserWindow::GetConstructor(isolate)->GetFunction()); + mate::Dictionary browser_window(isolate, templ->GetFunction()); browser_window.SetMethod( "fromId", - &mate::TrackableObject::FromWeakMapID); + &mate::TrackableObject::FromWeakMapID); browser_window.SetMethod( "getAllWindows", - &mate::TrackableObject::GetAll); + &mate::TrackableObject::GetAll); mate::Dictionary dict(isolate, exports); dict.Set("BrowserWindow", browser_window); diff --git a/atom/browser/api/atom_api_browser_window.h b/atom/browser/api/atom_api_browser_window.h index 60937af0fe2c..4433bf9f18bc 100644 --- a/atom/browser/api/atom_api_browser_window.h +++ b/atom/browser/api/atom_api_browser_window.h @@ -5,43 +5,21 @@ #ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_ #define ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_ -#include -#include #include #include +#include "atom/browser/api/atom_api_top_level_window.h" #include "atom/browser/api/atom_api_web_contents.h" -#include "atom/browser/native_window.h" -#include "atom/browser/native_window_observer.h" -#include "atom/common/api/atom_api_native_image.h" -#include "atom/common/key_weak_map.h" #include "base/cancelable_callback.h" -#include "base/memory/weak_ptr.h" -#include "content/public/browser/render_widget_host.h" -#include "native_mate/persistent_dictionary.h" - -class GURL; - -namespace gfx { -class Rect; -} - -namespace mate { -class Arguments; -class Dictionary; -} namespace atom { -class NativeWindow; - namespace api { -class BrowserWindow : public mate::TrackableObject, +class BrowserWindow : public TopLevelWindow, public content::RenderWidgetHost::InputEventObserver, public content::WebContentsObserver, - public ExtendedWebContentsObserver, - public NativeWindowObserver { + public ExtendedWebContentsObserver { public: static mate::WrappableBase* New(mate::Arguments* args); @@ -52,9 +30,9 @@ class BrowserWindow : public mate::TrackableObject, static v8::Local From(v8::Isolate* isolate, NativeWindow* native_window); - NativeWindow* window() const { return window_.get(); } - - int32_t ID() const; + base::WeakPtr GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } protected: BrowserWindow(v8::Isolate* isolate, @@ -80,184 +58,28 @@ class BrowserWindow : public mate::TrackableObject, void OnRendererResponsive() override; // NativeWindowObserver: - void WillCloseWindow(bool* prevent_default) override; void RequestPreferredWidth(int* width) override; void OnCloseButtonClicked(bool* prevent_default) override; + + // TopLevelWindow: void OnWindowClosed() override; - void OnWindowEndSession() override; void OnWindowBlur() override; void OnWindowFocus() override; - void OnWindowShow() override; - void OnWindowHide() override; - void OnWindowMaximize() override; - void OnWindowUnmaximize() override; - void OnWindowMinimize() override; - void OnWindowRestore() override; void OnWindowResize() override; - void OnWindowMove() override; - void OnWindowMoved() override; - void OnWindowScrollTouchBegin() override; - void OnWindowScrollTouchEnd() override; - void OnWindowSwipe(const std::string& direction) override; - void OnWindowSheetBegin() override; - void OnWindowSheetEnd() override; - void OnWindowEnterFullScreen() override; - void OnWindowLeaveFullScreen() override; - void OnWindowEnterHtmlFullScreen() override; - void OnWindowLeaveHtmlFullScreen() override; - void OnExecuteWindowsCommand(const std::string& command_name) override; - void OnTouchBarItemResult(const std::string& item_id, - const base::DictionaryValue& details) override; - void OnNewWindowForTab() override; + void Focus() override; + void Blur() override; + void SetBackgroundColor(const std::string& color_name) override; + void SetBrowserView(v8::Local value) override; + void SetVibrancy(mate::Arguments* args) override; - #if defined(OS_WIN) - void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override; - #endif - - base::WeakPtr GetWeakPtr() { - return weak_factory_.GetWeakPtr(); - } - - private: - void Init(v8::Isolate* isolate, - v8::Local wrapper, - const mate::Dictionary& options, - mate::Handle web_contents); - - // APIs for NativeWindow. - void Close(); - void Focus(); - void Blur(); - bool IsFocused(); - void Show(); - void ShowInactive(); - void Hide(); - bool IsVisible(); - bool IsEnabled(); - void SetEnabled(bool enable); - void Maximize(); - void Unmaximize(); - bool IsMaximized(); - void Minimize(); - void Restore(); - bool IsMinimized(); - void SetFullScreen(bool fullscreen); - bool IsFullscreen(); - void SetBounds(const gfx::Rect& bounds, mate::Arguments* args); - gfx::Rect GetBounds(); - void SetSize(int width, int height, mate::Arguments* args); - std::vector GetSize(); - void SetContentSize(int width, int height, mate::Arguments* args); - std::vector GetContentSize(); - void SetContentBounds(const gfx::Rect& bounds, mate::Arguments* args); - gfx::Rect GetContentBounds(); - void SetMinimumSize(int width, int height); - std::vector GetMinimumSize(); - void SetMaximumSize(int width, int height); - std::vector GetMaximumSize(); - void SetSheetOffset(double offsetY, mate::Arguments* args); - void SetResizable(bool resizable); - bool IsResizable(); - void SetMovable(bool movable); - #if defined(OS_WIN) || defined(OS_MACOSX) - void MoveTop(); - #endif - bool IsMovable(); - void SetMinimizable(bool minimizable); - bool IsMinimizable(); - void SetMaximizable(bool maximizable); - bool IsMaximizable(); - void SetFullScreenable(bool fullscreenable); - bool IsFullScreenable(); - void SetClosable(bool closable); - bool IsClosable(); - void SetAlwaysOnTop(bool top, mate::Arguments* args); - bool IsAlwaysOnTop(); - void Center(); - void SetPosition(int x, int y, mate::Arguments* args); - std::vector GetPosition(); - void SetTitle(const std::string& title); - std::string GetTitle(); - void FlashFrame(bool flash); - void SetSkipTaskbar(bool skip); - void SetSimpleFullScreen(bool simple_fullscreen); - bool IsSimpleFullScreen(); - void SetKiosk(bool kiosk); - bool IsKiosk(); - void SetBackgroundColor(const std::string& color_name); - void SetHasShadow(bool has_shadow); - bool HasShadow(); - void SetOpacity(const double opacity); - double GetOpacity(); + // BrowserWindow APIs. void FocusOnWebView(); void BlurWebView(); bool IsWebViewFocused(); - void SetRepresentedFilename(const std::string& filename); - std::string GetRepresentedFilename(); - void SetDocumentEdited(bool edited); - bool IsDocumentEdited(); - void SetIgnoreMouseEvents(bool ignore, mate::Arguments* args); - void SetContentProtection(bool enable); - void SetFocusable(bool focusable); - void SetProgressBar(double progress, mate::Arguments* args); - void SetOverlayIcon(const gfx::Image& overlay, - const std::string& description); - bool SetThumbarButtons(mate::Arguments* args); - void SetMenu(v8::Isolate* isolate, v8::Local menu); - void SetAutoHideMenuBar(bool auto_hide); - bool IsMenuBarAutoHide(); - void SetMenuBarVisibility(bool visible); - bool IsMenuBarVisible(); - void SetAspectRatio(double aspect_ratio, mate::Arguments* args); - void PreviewFile(const std::string& path, mate::Arguments* args); - void CloseFilePreview(); - void SetParentWindow(v8::Local value, mate::Arguments* args); - v8::Local GetParentWindow() const; - std::vector> GetChildWindows() const; - v8::Local GetBrowserView() const; - void SetBrowserView(v8::Local value); - void ResetBrowserView(); - bool IsModal() const; - v8::Local GetNativeWindowHandle(); + v8::Local GetWebContents(v8::Isolate* isolate); -#if defined(OS_WIN) - typedef base::Callback, - v8::Local)> MessageCallback; - - bool HookWindowMessage(UINT message, const MessageCallback& callback); - bool IsWindowMessageHooked(UINT message); - void UnhookWindowMessage(UINT message); - void UnhookAllWindowMessages(); - bool SetThumbnailClip(const gfx::Rect& region); - bool SetThumbnailToolTip(const std::string& tooltip); - void SetAppDetails(const mate::Dictionary& options); -#endif - -#if defined(TOOLKIT_VIEWS) - void SetIcon(mate::Handle icon); -#endif - - void SetVisibleOnAllWorkspaces(bool visible); - bool IsVisibleOnAllWorkspaces(); - - void SetAutoHideCursor(bool auto_hide); - - void SelectPreviousTab(); - void SelectNextTab(); - void MergeAllWindows(); - void MoveTabToNewWindow(); - void ToggleTabBar(); - void AddTabbedWindow(NativeWindow* window, mate::Arguments* args); - - void SetVibrancy(mate::Arguments* args); - void SetTouchBar(const std::vector& items); - void RefreshTouchBarItem(const std::string& item_id); - void SetEscapeTouchBarItem(const mate::PersistentDictionary& item); - - v8::Local WebContents(v8::Isolate* isolate); - - // Remove this window from parent window's |child_windows_|. - void RemoveFromParentChildWindows(); + private: + // Helpers. // Called when the window needs to update its draggable region. void UpdateDraggableRegions( @@ -274,29 +96,20 @@ class BrowserWindow : public mate::TrackableObject, // Dispatch unresponsive event to observers. void NotifyWindowUnresponsive(); -#if defined(OS_WIN) - typedef std::map MessageCallbackMap; - MessageCallbackMap messages_callback_map_; -#endif - -#if defined(OS_MACOSX) - std::vector draggable_regions_; -#endif + // Cleanup our WebContents observers. + void Cleanup(); // Closure that would be called when window is unresponsive when closing, // it should be cancelled when we can prove that the window is responsive. base::CancelableClosure window_unresponsive_closure_; - v8::Global browser_view_; +#if defined(OS_MACOSX) + std::vector draggable_regions_; +#endif + v8::Global web_contents_; - v8::Global menu_; - v8::Global parent_window_; - KeyWeakMap child_windows_; - api::WebContents* api_web_contents_; - std::unique_ptr window_; - base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(BrowserWindow); @@ -306,7 +119,6 @@ class BrowserWindow : public mate::TrackableObject, } // namespace atom - namespace mate { template<> diff --git a/atom/browser/api/atom_api_menu_mac.mm b/atom/browser/api/atom_api_menu_mac.mm index ed491730a114..cc08fa531509 100644 --- a/atom/browser/api/atom_api_menu_mac.mm +++ b/atom/browser/api/atom_api_menu_mac.mm @@ -35,7 +35,8 @@ void MenuMac::PopupAt(BrowserWindow* window, return; auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(), - native_window->GetWeakPtr(), window->ID(), x, y, + native_window->GetWeakPtr(), + window->weak_map_id(), x, y, positioning_item, callback); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup); } diff --git a/atom/browser/api/atom_api_menu_views.cc b/atom/browser/api/atom_api_menu_views.cc index 9042496453e5..bae1292dd1c8 100644 --- a/atom/browser/api/atom_api_menu_views.cc +++ b/atom/browser/api/atom_api_menu_views.cc @@ -43,7 +43,7 @@ void MenuViews::PopupAt(BrowserWindow* window, atom::UnresponsiveSuppressor suppressor; // Show the menu. - int32_t window_id = window->ID(); + int32_t window_id = window->weak_map_id(); auto close_callback = base::Bind( &MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback); menu_runners_[window_id] = std::unique_ptr(new MenuRunner( diff --git a/atom/browser/api/atom_api_top_level_window.cc b/atom/browser/api/atom_api_top_level_window.cc new file mode 100644 index 000000000000..17d941e73b54 --- /dev/null +++ b/atom/browser/api/atom_api_top_level_window.cc @@ -0,0 +1,1057 @@ +// 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_top_level_window.h" + +#include +#include + +#include "atom/browser/api/atom_api_browser_view.h" +#include "atom/browser/api/atom_api_menu.h" +#include "atom/common/color_util.h" +#include "atom/common/native_mate_converters/callback.h" +#include "atom/common/native_mate_converters/file_path_converter.h" +#include "atom/common/native_mate_converters/gfx_converter.h" +#include "atom/common/native_mate_converters/image_converter.h" +#include "atom/common/native_mate_converters/string16_converter.h" +#include "atom/common/native_mate_converters/value_converter.h" +#include "atom/common/options_switches.h" +#include "native_mate/handle.h" +#include "native_mate/persistent_dictionary.h" + +#if defined(TOOLKIT_VIEWS) +#include "atom/browser/native_window_views.h" +#endif + +#if defined(OS_WIN) +#include "atom/browser/ui/win/taskbar_host.h" +#include "ui/base/win/shell.h" +#endif + +#include "atom/common/node_includes.h" + +#if defined(OS_WIN) +namespace mate { + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle val, + atom::TaskbarHost::ThumbarButton* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + dict.Get("click", &(out->clicked_callback)); + dict.Get("tooltip", &(out->tooltip)); + dict.Get("flags", &out->flags); + return dict.Get("icon", &(out->icon)); + } +}; + +} // namespace mate +#endif + +namespace atom { + +namespace api { + +namespace { + +// Converts binary data to Buffer. +v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { + auto buffer = node::Buffer::Copy(isolate, static_cast(val), size); + if (buffer.IsEmpty()) + return v8::Null(isolate); + else + return buffer.ToLocalChecked(); +} + +} // namespace + +TopLevelWindow::TopLevelWindow(v8::Isolate* isolate, + v8::Local wrapper, + const mate::Dictionary& options) + : weak_factory_(this) { + // The parent window. + mate::Handle parent; + if (options.Get("parent", &parent) && !parent.IsEmpty()) + parent_window_.Reset(isolate, parent.ToV8()); + +#if defined(ENABLE_OSR) + // Offscreen windows are always created frameless. + mate::Dictionary web_preferences; + bool offscreen; + if (options.Get(options::kWebPreferences, &web_preferences) && + web_preferences.Get("offscreen", &offscreen) && + offscreen) { + const_cast(options).Set(options::kFrame, false); + } +#endif + + // Creates NativeWindow. + window_.reset(NativeWindow::Create( + options, + parent.IsEmpty() ? nullptr : parent->window_.get())); + window_->AddObserver(this); + +#if defined(TOOLKIT_VIEWS) + // Sets the window icon. + mate::Handle icon; + if (options.Get(options::kIcon, &icon) && !icon.IsEmpty()) + SetIcon(icon); +#endif + + AttachAsUserData(window_.get()); + + // We can only append this window to parent window's child windows after this + // window's JS wrapper gets initialized. + if (!parent.IsEmpty()) + parent->child_windows_.Set(isolate, weak_map_id(), wrapper); +} + +TopLevelWindow::~TopLevelWindow() { + if (!window_->IsClosed()) + window_->CloseImmediately(); + + // Destroy the native window in next tick because the native code might be + // iterating all windows. + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release()); +} + +void TopLevelWindow::WillCloseWindow(bool* prevent_default) { + *prevent_default = Emit("close"); +} + +void TopLevelWindow::OnWindowClosed() { + RemoveFromWeakMap(); + window_->RemoveObserver(this); + + // We can not call Destroy here because we need to call Emit first, but we + // also do not want any method to be used, so just mark as destroyed here. + MarkDestroyed(); + + Emit("closed"); + + RemoveFromParentChildWindows(); + ResetBrowserView(); + + // Destroy the native class when window is closed. + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, GetDestroyClosure()); +} + +void TopLevelWindow::OnWindowEndSession() { + Emit("session-end"); +} + +void TopLevelWindow::OnWindowBlur() { + Emit("blur"); +} + +void TopLevelWindow::OnWindowFocus() { + Emit("focus"); +} + +void TopLevelWindow::OnWindowShow() { + Emit("show"); +} + +void TopLevelWindow::OnWindowHide() { + Emit("hide"); +} + +void TopLevelWindow::OnWindowMaximize() { + Emit("maximize"); +} + +void TopLevelWindow::OnWindowUnmaximize() { + Emit("unmaximize"); +} + +void TopLevelWindow::OnWindowMinimize() { + Emit("minimize"); +} + +void TopLevelWindow::OnWindowRestore() { + Emit("restore"); +} + +void TopLevelWindow::OnWindowResize() { + Emit("resize"); +} + +void TopLevelWindow::OnWindowMove() { + Emit("move"); +} + +void TopLevelWindow::OnWindowMoved() { + Emit("moved"); +} + +void TopLevelWindow::OnWindowEnterFullScreen() { + Emit("enter-full-screen"); +} + +void TopLevelWindow::OnWindowLeaveFullScreen() { + Emit("leave-full-screen"); +} + +void TopLevelWindow::OnWindowScrollTouchBegin() { + Emit("scroll-touch-begin"); +} + +void TopLevelWindow::OnWindowScrollTouchEnd() { + Emit("scroll-touch-end"); +} + +void TopLevelWindow::OnWindowSwipe(const std::string& direction) { + Emit("swipe", direction); +} + +void TopLevelWindow::OnWindowSheetBegin() { + Emit("sheet-begin"); +} + +void TopLevelWindow::OnWindowSheetEnd() { + Emit("sheet-end"); +} + +void TopLevelWindow::OnWindowEnterHtmlFullScreen() { + Emit("enter-html-full-screen"); +} + +void TopLevelWindow::OnWindowLeaveHtmlFullScreen() { + Emit("leave-html-full-screen"); +} + +void TopLevelWindow::OnExecuteWindowsCommand(const std::string& command_name) { + Emit("app-command", command_name); +} + +void TopLevelWindow::OnTouchBarItemResult(const std::string& item_id, + const base::DictionaryValue& details) { + Emit("-touch-bar-interaction", item_id, details); +} + +void TopLevelWindow::OnNewWindowForTab() { + Emit("new-window-for-tab"); +} + +#if defined(OS_WIN) +void TopLevelWindow::OnWindowMessage(UINT message, + WPARAM w_param, + LPARAM l_param) { + if (IsWindowMessageHooked(message)) { + messages_callback_map_[message].Run( + ToBuffer(isolate(), static_cast(&w_param), sizeof(WPARAM)), + ToBuffer(isolate(), static_cast(&l_param), sizeof(LPARAM))); + } +} +#endif + +void TopLevelWindow::Close() { + window_->Close(); +} + +void TopLevelWindow::Focus() { + window_->Focus(true); +} + +void TopLevelWindow::Blur() { + window_->Focus(false); +} + +bool TopLevelWindow::IsFocused() { + return window_->IsFocused(); +} + +void TopLevelWindow::Show() { + window_->Show(); +} + +void TopLevelWindow::ShowInactive() { + // This method doesn't make sense for modal window. + if (IsModal()) + return; + window_->ShowInactive(); +} + +void TopLevelWindow::Hide() { + window_->Hide(); +} + +bool TopLevelWindow::IsVisible() { + return window_->IsVisible(); +} + +bool TopLevelWindow::IsEnabled() { + return window_->IsEnabled(); +} + +void TopLevelWindow::SetEnabled(bool enable) { + window_->SetEnabled(enable); +} + +void TopLevelWindow::Maximize() { + window_->Maximize(); +} + +void TopLevelWindow::Unmaximize() { + window_->Unmaximize(); +} + +bool TopLevelWindow::IsMaximized() { + return window_->IsMaximized(); +} + +void TopLevelWindow::Minimize() { + window_->Minimize(); +} + +void TopLevelWindow::Restore() { + window_->Restore(); +} + +bool TopLevelWindow::IsMinimized() { + return window_->IsMinimized(); +} + +void TopLevelWindow::SetFullScreen(bool fullscreen) { + window_->SetFullScreen(fullscreen); +} + +bool TopLevelWindow::IsFullscreen() { + return window_->IsFullscreen(); +} + +void TopLevelWindow::SetBounds(const gfx::Rect& bounds, mate::Arguments* args) { + bool animate = false; + args->GetNext(&animate); + window_->SetBounds(bounds, animate); +} + +gfx::Rect TopLevelWindow::GetBounds() { + return window_->GetBounds(); +} + +void TopLevelWindow::SetContentBounds(const gfx::Rect& bounds, + mate::Arguments* args) { + bool animate = false; + args->GetNext(&animate); + window_->SetContentBounds(bounds, animate); +} + +gfx::Rect TopLevelWindow::GetContentBounds() { + return window_->GetContentBounds(); +} + +void TopLevelWindow::SetSize(int width, int height, mate::Arguments* args) { + bool animate = false; + args->GetNext(&animate); + window_->SetSize(gfx::Size(width, height), animate); +} + +std::vector TopLevelWindow::GetSize() { + std::vector result(2); + gfx::Size size = window_->GetSize(); + result[0] = size.width(); + result[1] = size.height(); + return result; +} + +void TopLevelWindow::SetContentSize(int width, int height, + mate::Arguments* args) { + bool animate = false; + args->GetNext(&animate); + window_->SetContentSize(gfx::Size(width, height), animate); +} + +std::vector TopLevelWindow::GetContentSize() { + std::vector result(2); + gfx::Size size = window_->GetContentSize(); + result[0] = size.width(); + result[1] = size.height(); + return result; +} + +void TopLevelWindow::SetMinimumSize(int width, int height) { + window_->SetMinimumSize(gfx::Size(width, height)); +} + +std::vector TopLevelWindow::GetMinimumSize() { + std::vector result(2); + gfx::Size size = window_->GetMinimumSize(); + result[0] = size.width(); + result[1] = size.height(); + return result; +} + +void TopLevelWindow::SetMaximumSize(int width, int height) { + window_->SetMaximumSize(gfx::Size(width, height)); +} + +std::vector TopLevelWindow::GetMaximumSize() { + std::vector result(2); + gfx::Size size = window_->GetMaximumSize(); + result[0] = size.width(); + result[1] = size.height(); + return result; +} + +void TopLevelWindow::SetSheetOffset(double offsetY, mate::Arguments* args) { + double offsetX = 0.0; + args->GetNext(&offsetX); + window_->SetSheetOffset(offsetX, offsetY); +} + +void TopLevelWindow::SetResizable(bool resizable) { + window_->SetResizable(resizable); +} + +bool TopLevelWindow::IsResizable() { + return window_->IsResizable(); +} + +void TopLevelWindow::SetMovable(bool movable) { + window_->SetMovable(movable); +} + +bool TopLevelWindow::IsMovable() { + return window_->IsMovable(); +} + +void TopLevelWindow::SetMinimizable(bool minimizable) { + window_->SetMinimizable(minimizable); +} + +bool TopLevelWindow::IsMinimizable() { + return window_->IsMinimizable(); +} + +void TopLevelWindow::SetMaximizable(bool maximizable) { + window_->SetMaximizable(maximizable); +} + +bool TopLevelWindow::IsMaximizable() { + return window_->IsMaximizable(); +} + +void TopLevelWindow::SetFullScreenable(bool fullscreenable) { + window_->SetFullScreenable(fullscreenable); +} + +bool TopLevelWindow::IsFullScreenable() { + return window_->IsFullScreenable(); +} + +void TopLevelWindow::SetClosable(bool closable) { + window_->SetClosable(closable); +} + +bool TopLevelWindow::IsClosable() { + return window_->IsClosable(); +} + +void TopLevelWindow::SetAlwaysOnTop(bool top, mate::Arguments* args) { + std::string level = "floating"; + int relative_level = 0; + args->GetNext(&level); + args->GetNext(&relative_level); + + std::string error; + window_->SetAlwaysOnTop(top, level, relative_level, &error); + + if (!error.empty()) + args->ThrowError(error); +} + +bool TopLevelWindow::IsAlwaysOnTop() { + return window_->IsAlwaysOnTop(); +} + +void TopLevelWindow::Center() { + window_->Center(); +} + +void TopLevelWindow::SetPosition(int x, int y, mate::Arguments* args) { + bool animate = false; + args->GetNext(&animate); + window_->SetPosition(gfx::Point(x, y), animate); +} + +std::vector TopLevelWindow::GetPosition() { + std::vector result(2); + gfx::Point pos = window_->GetPosition(); + result[0] = pos.x(); + result[1] = pos.y(); + return result; +} + +#if defined(OS_WIN) || defined(OS_MACOSX) +void TopLevelWindow::MoveTop() { + window_->MoveTop(); +} +#endif + +void TopLevelWindow::SetTitle(const std::string& title) { + window_->SetTitle(title); +} + +std::string TopLevelWindow::GetTitle() { + return window_->GetTitle(); +} + +void TopLevelWindow::FlashFrame(bool flash) { + window_->FlashFrame(flash); +} + +void TopLevelWindow::SetSkipTaskbar(bool skip) { + window_->SetSkipTaskbar(skip); +} + +void TopLevelWindow::SetSimpleFullScreen(bool simple_fullscreen) { + window_->SetSimpleFullScreen(simple_fullscreen); +} + +bool TopLevelWindow::IsSimpleFullScreen() { + return window_->IsSimpleFullScreen(); +} + +void TopLevelWindow::SetKiosk(bool kiosk) { + window_->SetKiosk(kiosk); +} + +bool TopLevelWindow::IsKiosk() { + return window_->IsKiosk(); +} + +void TopLevelWindow::SetBackgroundColor(const std::string& color_name) { + SkColor color = ParseHexColor(color_name); + window_->SetBackgroundColor(color); +} + +void TopLevelWindow::SetHasShadow(bool has_shadow) { + window_->SetHasShadow(has_shadow); +} + +bool TopLevelWindow::HasShadow() { + return window_->HasShadow(); +} + +void TopLevelWindow::SetOpacity(const double opacity) { + window_->SetOpacity(opacity); +} + +double TopLevelWindow::GetOpacity() { + return window_->GetOpacity(); +} + +void TopLevelWindow::SetRepresentedFilename(const std::string& filename) { + window_->SetRepresentedFilename(filename); +} + +std::string TopLevelWindow::GetRepresentedFilename() { + return window_->GetRepresentedFilename(); +} + +void TopLevelWindow::SetDocumentEdited(bool edited) { + window_->SetDocumentEdited(edited); +} + +bool TopLevelWindow::IsDocumentEdited() { + return window_->IsDocumentEdited(); +} + +void TopLevelWindow::SetIgnoreMouseEvents(bool ignore, mate::Arguments* args) { + mate::Dictionary options; + bool forward = false; + args->GetNext(&options) && options.Get("forward", &forward); + return window_->SetIgnoreMouseEvents(ignore, forward); +} + +void TopLevelWindow::SetContentProtection(bool enable) { + return window_->SetContentProtection(enable); +} + +void TopLevelWindow::SetFocusable(bool focusable) { + return window_->SetFocusable(focusable); +} + +void TopLevelWindow::SetMenu(v8::Isolate* isolate, v8::Local value) { + mate::Handle menu; + if (value->IsObject() && + mate::V8ToString(value->ToObject()->GetConstructorName()) == "Menu" && + mate::ConvertFromV8(isolate, value, &menu) && + !menu.IsEmpty()) { + menu_.Reset(isolate, menu.ToV8()); + window_->SetMenu(menu->model()); + } else if (value->IsNull()) { + menu_.Reset(); + window_->SetMenu(nullptr); + } else { + isolate->ThrowException(v8::Exception::TypeError( + mate::StringToV8(isolate, "Invalid Menu"))); + } +} + +void TopLevelWindow::SetParentWindow(v8::Local value, + mate::Arguments* args) { + if (IsModal()) { + args->ThrowError("Can not be called for modal window"); + return; + } + + mate::Handle parent; + if (value->IsNull() || value->IsUndefined()) { + RemoveFromParentChildWindows(); + parent_window_.Reset(); + window_->SetParentWindow(nullptr); + } else if (mate::ConvertFromV8(isolate(), value, &parent)) { + parent_window_.Reset(isolate(), value); + window_->SetParentWindow(parent->window_.get()); + parent->child_windows_.Set(isolate(), weak_map_id(), GetWrapper()); + } else { + args->ThrowError("Must pass TopLevelWindow instance or null"); + } +} + +void TopLevelWindow::SetBrowserView(v8::Local value) { + ResetBrowserView(); + + mate::Handle browser_view; + if (value->IsNull() || value->IsUndefined()) { + window_->SetBrowserView(nullptr); + } else if (mate::ConvertFromV8(isolate(), value, &browser_view)) { + window_->SetBrowserView(browser_view->view()); + browser_view->web_contents()->SetOwnerWindow(window_.get()); + browser_view_.Reset(isolate(), value); + } +} + +v8::Local TopLevelWindow::GetNativeWindowHandle() { + gfx::AcceleratedWidget handle = window_->GetAcceleratedWidget(); + return ToBuffer(isolate(), static_cast(&handle), sizeof(handle)); +} + +void TopLevelWindow::SetProgressBar(double progress, mate::Arguments* args) { + mate::Dictionary options; + std::string mode; + args->GetNext(&options) && options.Get("mode", &mode); + + NativeWindow::ProgressState state = NativeWindow::PROGRESS_NORMAL; + if (mode == "error") + state = NativeWindow::PROGRESS_ERROR; + else if (mode == "paused") + state = NativeWindow::PROGRESS_PAUSED; + else if (mode == "indeterminate") + state = NativeWindow::PROGRESS_INDETERMINATE; + else if (mode == "none") + state = NativeWindow::PROGRESS_NONE; + + window_->SetProgressBar(progress, state); +} + +void TopLevelWindow::SetOverlayIcon(const gfx::Image& overlay, + const std::string& description) { + window_->SetOverlayIcon(overlay, description); +} + +void TopLevelWindow::SetVisibleOnAllWorkspaces(bool visible) { + return window_->SetVisibleOnAllWorkspaces(visible); +} + +bool TopLevelWindow::IsVisibleOnAllWorkspaces() { + return window_->IsVisibleOnAllWorkspaces(); +} + +void TopLevelWindow::SetAutoHideCursor(bool auto_hide) { + window_->SetAutoHideCursor(auto_hide); +} + +void TopLevelWindow::SetVibrancy(mate::Arguments* args) { + std::string type; + args->GetNext(&type); + window_->SetVibrancy(type); +} + +void TopLevelWindow::SetTouchBar( + const std::vector& items) { + window_->SetTouchBar(items); +} + +void TopLevelWindow::RefreshTouchBarItem(const std::string& item_id) { + window_->RefreshTouchBarItem(item_id); +} + +void TopLevelWindow::SetEscapeTouchBarItem( + const mate::PersistentDictionary& item) { + window_->SetEscapeTouchBarItem(item); +} + +void TopLevelWindow::SelectPreviousTab() { + window_->SelectPreviousTab(); +} + +void TopLevelWindow::SelectNextTab() { + window_->SelectNextTab(); +} + +void TopLevelWindow::MergeAllWindows() { + window_->MergeAllWindows(); +} + +void TopLevelWindow::MoveTabToNewWindow() { + window_->MoveTabToNewWindow(); +} + +void TopLevelWindow::ToggleTabBar() { + window_->ToggleTabBar(); +} + +void TopLevelWindow::AddTabbedWindow(NativeWindow* window, + mate::Arguments* args) { + if (!window_->AddTabbedWindow(window)) + args->ThrowError("AddTabbedWindow cannot be called by a window on itself."); +} + +void TopLevelWindow::SetAutoHideMenuBar(bool auto_hide) { + window_->SetAutoHideMenuBar(auto_hide); +} + +bool TopLevelWindow::IsMenuBarAutoHide() { + return window_->IsMenuBarAutoHide(); +} + +void TopLevelWindow::SetMenuBarVisibility(bool visible) { + window_->SetMenuBarVisibility(visible); +} + +bool TopLevelWindow::IsMenuBarVisible() { + return window_->IsMenuBarVisible(); +} + +void TopLevelWindow::SetAspectRatio(double aspect_ratio, + mate::Arguments* args) { + gfx::Size extra_size; + args->GetNext(&extra_size); + window_->SetAspectRatio(aspect_ratio, extra_size); +} + +void TopLevelWindow::PreviewFile(const std::string& path, + mate::Arguments* args) { + std::string display_name; + if (!args->GetNext(&display_name)) + display_name = path; + window_->PreviewFile(path, display_name); +} + +void TopLevelWindow::CloseFilePreview() { + window_->CloseFilePreview(); +} + +v8::Local TopLevelWindow::GetParentWindow() const { + if (parent_window_.IsEmpty()) + return v8::Null(isolate()); + else + return v8::Local::New(isolate(), parent_window_); +} + +std::vector> TopLevelWindow::GetChildWindows() const { + return child_windows_.Values(isolate()); +} + +v8::Local TopLevelWindow::GetBrowserView() const { + if (browser_view_.IsEmpty()) { + return v8::Null(isolate()); + } + + return v8::Local::New(isolate(), browser_view_); +} + +bool TopLevelWindow::IsModal() const { + return window_->is_modal(); +} + +bool TopLevelWindow::SetThumbarButtons(mate::Arguments* args) { +#if defined(OS_WIN) + std::vector buttons; + if (!args->GetNext(&buttons)) { + args->ThrowError(); + return false; + } + auto window = static_cast(window_.get()); + return window->taskbar_host().SetThumbarButtons( + window_->GetAcceleratedWidget(), buttons); +#else + return false; +#endif +} + +#if defined(TOOLKIT_VIEWS) +void TopLevelWindow::SetIcon(mate::Handle icon) { +#if defined(OS_WIN) + static_cast(window_.get())->SetIcon( + icon->GetHICON(GetSystemMetrics(SM_CXSMICON)), + icon->GetHICON(GetSystemMetrics(SM_CXICON))); +#elif defined(USE_X11) + static_cast(window_.get())->SetIcon( + icon->image().AsImageSkia()); +#endif +} +#endif + +#if defined(OS_WIN) +bool TopLevelWindow::HookWindowMessage(UINT message, + const MessageCallback& callback) { + messages_callback_map_[message] = callback; + return true; +} + +void TopLevelWindow::UnhookWindowMessage(UINT message) { + if (!ContainsKey(messages_callback_map_, message)) + return; + + messages_callback_map_.erase(message); +} + +bool TopLevelWindow::IsWindowMessageHooked(UINT message) { + return ContainsKey(messages_callback_map_, message); +} + +void TopLevelWindow::UnhookAllWindowMessages() { + messages_callback_map_.clear(); +} + +bool TopLevelWindow::SetThumbnailClip(const gfx::Rect& region) { + auto* window = static_cast(window_.get()); + return window->taskbar_host().SetThumbnailClip( + window_->GetAcceleratedWidget(), region); +} + +bool TopLevelWindow::SetThumbnailToolTip(const std::string& tooltip) { + auto* window = static_cast(window_.get()); + return window->taskbar_host().SetThumbnailToolTip( + window_->GetAcceleratedWidget(), tooltip); +} + +void TopLevelWindow::SetAppDetails(const mate::Dictionary& options) { + base::string16 app_id; + base::FilePath app_icon_path; + int app_icon_index = 0; + base::string16 relaunch_command; + base::string16 relaunch_display_name; + + options.Get("appId", &app_id); + options.Get("appIconPath", &app_icon_path); + options.Get("appIconIndex", &app_icon_index); + options.Get("relaunchCommand", &relaunch_command); + options.Get("relaunchDisplayName", &relaunch_display_name); + + ui::win::SetAppDetailsForWindow( + app_id, app_icon_path, app_icon_index, + relaunch_command, relaunch_display_name, + window_->GetAcceleratedWidget()); +} +#endif + +int32_t TopLevelWindow::GetID() const { + return weak_map_id(); +} + +void TopLevelWindow::ResetBrowserView() { + if (browser_view_.IsEmpty()) + return; + + mate::Handle browser_view; + if (mate::ConvertFromV8(isolate(), GetBrowserView(), &browser_view) && + !browser_view.IsEmpty()) { + browser_view->web_contents()->SetOwnerWindow(nullptr); + } + + browser_view_.Reset(); +} + +void TopLevelWindow::RemoveFromParentChildWindows() { + if (parent_window_.IsEmpty()) + return; + + mate::Handle parent; + if (!mate::ConvertFromV8(isolate(), GetParentWindow(), &parent) || + parent.IsEmpty()) { + return; + } + + parent->child_windows_.Remove(weak_map_id()); +} + +// static +mate::WrappableBase* TopLevelWindow::New(mate::Arguments* args) { + mate::Dictionary options; + if (!(args->Length() == 1 && args->GetNext(&options))) + options = mate::Dictionary::CreateEmpty(args->isolate()); + return new TopLevelWindow(args->isolate(), args->GetThis(), options); +} + +// static +void TopLevelWindow::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) { + prototype->SetClassName(mate::StringToV8(isolate, "TopLevelWindow")); + mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) + .MakeDestroyable() + .SetMethod("close", &TopLevelWindow::Close) + .SetMethod("focus", &TopLevelWindow::Focus) + .SetMethod("blur", &TopLevelWindow::Blur) + .SetMethod("isFocused", &TopLevelWindow::IsFocused) + .SetMethod("show", &TopLevelWindow::Show) + .SetMethod("showInactive", &TopLevelWindow::ShowInactive) + .SetMethod("hide", &TopLevelWindow::Hide) + .SetMethod("isVisible", &TopLevelWindow::IsVisible) + .SetMethod("isEnabled", &TopLevelWindow::IsEnabled) + .SetMethod("setEnabled", & TopLevelWindow::SetEnabled) + .SetMethod("maximize", &TopLevelWindow::Maximize) + .SetMethod("unmaximize", &TopLevelWindow::Unmaximize) + .SetMethod("isMaximized", &TopLevelWindow::IsMaximized) + .SetMethod("minimize", &TopLevelWindow::Minimize) + .SetMethod("restore", &TopLevelWindow::Restore) + .SetMethod("isMinimized", &TopLevelWindow::IsMinimized) + .SetMethod("setFullScreen", &TopLevelWindow::SetFullScreen) + .SetMethod("isFullScreen", &TopLevelWindow::IsFullscreen) + .SetMethod("setBounds", &TopLevelWindow::SetBounds) + .SetMethod("getBounds", &TopLevelWindow::GetBounds) + .SetMethod("setSize", &TopLevelWindow::SetSize) + .SetMethod("getSize", &TopLevelWindow::GetSize) + .SetMethod("setContentBounds", &TopLevelWindow::SetContentBounds) + .SetMethod("getContentBounds", &TopLevelWindow::GetContentBounds) + .SetMethod("setContentSize", &TopLevelWindow::SetContentSize) + .SetMethod("getContentSize", &TopLevelWindow::GetContentSize) + .SetMethod("setMinimumSize", &TopLevelWindow::SetMinimumSize) + .SetMethod("getMinimumSize", &TopLevelWindow::GetMinimumSize) + .SetMethod("setMaximumSize", &TopLevelWindow::SetMaximumSize) + .SetMethod("getMaximumSize", &TopLevelWindow::GetMaximumSize) + .SetMethod("setSheetOffset", &TopLevelWindow::SetSheetOffset) + .SetMethod("setResizable", &TopLevelWindow::SetResizable) + .SetMethod("isResizable", &TopLevelWindow::IsResizable) + .SetMethod("setMovable", &TopLevelWindow::SetMovable) +#if defined(OS_WIN) || defined(OS_MACOSX) + .SetMethod("moveTop" , &TopLevelWindow::MoveTop) +#endif + .SetMethod("isMovable", &TopLevelWindow::IsMovable) + .SetMethod("setMinimizable", &TopLevelWindow::SetMinimizable) + .SetMethod("isMinimizable", &TopLevelWindow::IsMinimizable) + .SetMethod("setMaximizable", &TopLevelWindow::SetMaximizable) + .SetMethod("isMaximizable", &TopLevelWindow::IsMaximizable) + .SetMethod("setFullScreenable", &TopLevelWindow::SetFullScreenable) + .SetMethod("isFullScreenable", &TopLevelWindow::IsFullScreenable) + .SetMethod("setClosable", &TopLevelWindow::SetClosable) + .SetMethod("isClosable", &TopLevelWindow::IsClosable) + .SetMethod("setAlwaysOnTop", &TopLevelWindow::SetAlwaysOnTop) + .SetMethod("isAlwaysOnTop", &TopLevelWindow::IsAlwaysOnTop) + .SetMethod("center", &TopLevelWindow::Center) + .SetMethod("setPosition", &TopLevelWindow::SetPosition) + .SetMethod("getPosition", &TopLevelWindow::GetPosition) + .SetMethod("setTitle", &TopLevelWindow::SetTitle) + .SetMethod("getTitle", &TopLevelWindow::GetTitle) + .SetMethod("flashFrame", &TopLevelWindow::FlashFrame) + .SetMethod("setSkipTaskbar", &TopLevelWindow::SetSkipTaskbar) + .SetMethod("setSimpleFullScreen", &TopLevelWindow::SetSimpleFullScreen) + .SetMethod("isSimpleFullScreen", &TopLevelWindow::IsSimpleFullScreen) + .SetMethod("setKiosk", &TopLevelWindow::SetKiosk) + .SetMethod("isKiosk", &TopLevelWindow::IsKiosk) + .SetMethod("setBackgroundColor", &TopLevelWindow::SetBackgroundColor) + .SetMethod("setHasShadow", &TopLevelWindow::SetHasShadow) + .SetMethod("hasShadow", &TopLevelWindow::HasShadow) + .SetMethod("setOpacity", &TopLevelWindow::SetOpacity) + .SetMethod("getOpacity", &TopLevelWindow::GetOpacity) + .SetMethod("setRepresentedFilename", + &TopLevelWindow::SetRepresentedFilename) + .SetMethod("getRepresentedFilename", + &TopLevelWindow::GetRepresentedFilename) + .SetMethod("setDocumentEdited", &TopLevelWindow::SetDocumentEdited) + .SetMethod("isDocumentEdited", &TopLevelWindow::IsDocumentEdited) + .SetMethod("setIgnoreMouseEvents", &TopLevelWindow::SetIgnoreMouseEvents) + .SetMethod("setContentProtection", &TopLevelWindow::SetContentProtection) + .SetMethod("setFocusable", &TopLevelWindow::SetFocusable) + .SetMethod("setMenu", &TopLevelWindow::SetMenu) +#if !defined(OS_WIN) + .SetMethod("setParentWindow", &TopLevelWindow::SetParentWindow) +#endif + .SetMethod("setBrowserView", &TopLevelWindow::SetBrowserView) + .SetMethod("getNativeWindowHandle", + &TopLevelWindow::GetNativeWindowHandle) + .SetMethod("setProgressBar", &TopLevelWindow::SetProgressBar) + .SetMethod("setOverlayIcon", &TopLevelWindow::SetOverlayIcon) + .SetMethod("setVisibleOnAllWorkspaces", + &TopLevelWindow::SetVisibleOnAllWorkspaces) + .SetMethod("isVisibleOnAllWorkspaces", + &TopLevelWindow::IsVisibleOnAllWorkspaces) +#if defined(OS_MACOSX) + .SetMethod("setAutoHideCursor", &TopLevelWindow::SetAutoHideCursor) +#endif + .SetMethod("setVibrancy", &TopLevelWindow::SetVibrancy) + .SetMethod("_setTouchBarItems", &TopLevelWindow::SetTouchBar) + .SetMethod("_refreshTouchBarItem", &TopLevelWindow::RefreshTouchBarItem) + .SetMethod("_setEscapeTouchBarItem", + &TopLevelWindow::SetEscapeTouchBarItem) +#if defined(OS_MACOSX) + .SetMethod("selectPreviousTab", &TopLevelWindow::SelectPreviousTab) + .SetMethod("selectNextTab", &TopLevelWindow::SelectNextTab) + .SetMethod("mergeAllWindows", &TopLevelWindow::MergeAllWindows) + .SetMethod("moveTabToNewWindow", &TopLevelWindow::MoveTabToNewWindow) + .SetMethod("toggleTabBar", &TopLevelWindow::ToggleTabBar) + .SetMethod("addTabbedWindow", &TopLevelWindow::AddTabbedWindow) +#endif + .SetMethod("setAutoHideMenuBar", &TopLevelWindow::SetAutoHideMenuBar) + .SetMethod("isMenuBarAutoHide", &TopLevelWindow::IsMenuBarAutoHide) + .SetMethod("setMenuBarVisibility", &TopLevelWindow::SetMenuBarVisibility) + .SetMethod("isMenuBarVisible", &TopLevelWindow::IsMenuBarVisible) + .SetMethod("setAspectRatio", &TopLevelWindow::SetAspectRatio) + .SetMethod("previewFile", &TopLevelWindow::PreviewFile) + .SetMethod("closeFilePreview", &TopLevelWindow::CloseFilePreview) + .SetMethod("getParentWindow", &TopLevelWindow::GetParentWindow) + .SetMethod("getChildWindows", &TopLevelWindow::GetChildWindows) + .SetMethod("getBrowserView", &TopLevelWindow::GetBrowserView) + .SetMethod("isModal", &TopLevelWindow::IsModal) + .SetMethod("setThumbarButtons", &TopLevelWindow::SetThumbarButtons) +#if defined(TOOLKIT_VIEWS) + .SetMethod("setIcon", &TopLevelWindow::SetIcon) +#endif +#if defined(OS_WIN) + .SetMethod("hookWindowMessage", &TopLevelWindow::HookWindowMessage) + .SetMethod("isWindowMessageHooked", + &TopLevelWindow::IsWindowMessageHooked) + .SetMethod("unhookWindowMessage", &TopLevelWindow::UnhookWindowMessage) + .SetMethod("unhookAllWindowMessages", + &TopLevelWindow::UnhookAllWindowMessages) + .SetMethod("setThumbnailClip", &TopLevelWindow::SetThumbnailClip) + .SetMethod("setThumbnailToolTip", &TopLevelWindow::SetThumbnailToolTip) + .SetMethod("setAppDetails", &TopLevelWindow::SetAppDetails) +#endif + .SetProperty("id", &TopLevelWindow::GetID); +} + +} // namespace api + +} // namespace atom + +namespace { + +using atom::api::TopLevelWindow; + +void Initialize(v8::Local exports, v8::Local unused, + v8::Local context, void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + TopLevelWindow::SetConstructor(isolate, base::Bind(&TopLevelWindow::New)); + + mate::Dictionary constructor( + isolate, TopLevelWindow::GetConstructor(isolate)->GetFunction()); + constructor.SetMethod("fromId", + &mate::TrackableObject::FromWeakMapID); + constructor.SetMethod("getAllWindows", + &mate::TrackableObject::GetAll); + + mate::Dictionary dict(isolate, exports); + dict.Set("TopLevelWindow", constructor); +} + +} // namespace + +NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_top_level_window, Initialize) diff --git a/atom/browser/api/atom_api_top_level_window.h b/atom/browser/api/atom_api_top_level_window.h new file mode 100644 index 000000000000..86e57a5ecea6 --- /dev/null +++ b/atom/browser/api/atom_api_top_level_window.h @@ -0,0 +1,226 @@ +// 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_TOP_LEVEL_WINDOW_H_ +#define ATOM_BROWSER_API_ATOM_API_TOP_LEVEL_WINDOW_H_ + +#include +#include +#include +#include + +#include "atom/browser/api/trackable_object.h" +#include "atom/browser/native_window.h" +#include "atom/browser/native_window_observer.h" +#include "atom/common/api/atom_api_native_image.h" +#include "native_mate/handle.h" + +namespace atom { + +namespace api { + +class TopLevelWindow : public mate::TrackableObject, + public NativeWindowObserver { + public: + static mate::WrappableBase* New(mate::Arguments* args); + + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + + base::WeakPtr GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } + + NativeWindow* window() const { return window_.get(); } + + protected: + TopLevelWindow(v8::Isolate* isolate, + v8::Local wrapper, + const mate::Dictionary& options); + ~TopLevelWindow() override; + + // NativeWindowObserver: + void WillCloseWindow(bool* prevent_default) override; + void OnWindowClosed() override; + void OnWindowEndSession() override; + void OnWindowBlur() override; + void OnWindowFocus() override; + void OnWindowShow() override; + void OnWindowHide() override; + void OnWindowMaximize() override; + void OnWindowUnmaximize() override; + void OnWindowMinimize() override; + void OnWindowRestore() override; + void OnWindowResize() override; + void OnWindowMove() override; + void OnWindowMoved() override; + void OnWindowScrollTouchBegin() override; + void OnWindowScrollTouchEnd() override; + void OnWindowSwipe(const std::string& direction) override; + void OnWindowSheetBegin() override; + void OnWindowSheetEnd() override; + void OnWindowEnterFullScreen() override; + void OnWindowLeaveFullScreen() override; + void OnWindowEnterHtmlFullScreen() override; + void OnWindowLeaveHtmlFullScreen() override; + void OnExecuteWindowsCommand(const std::string& command_name) override; + void OnTouchBarItemResult(const std::string& item_id, + const base::DictionaryValue& details) override; + void OnNewWindowForTab() override; + #if defined(OS_WIN) + void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override; + #endif + + // Public APIs of NativeWindow. + void Close(); + virtual void Focus(); + virtual void Blur(); + bool IsFocused(); + void Show(); + void ShowInactive(); + void Hide(); + bool IsVisible(); + bool IsEnabled(); + void SetEnabled(bool enable); + void Maximize(); + void Unmaximize(); + bool IsMaximized(); + void Minimize(); + void Restore(); + bool IsMinimized(); + void SetFullScreen(bool fullscreen); + bool IsFullscreen(); + void SetBounds(const gfx::Rect& bounds, mate::Arguments* args); + gfx::Rect GetBounds(); + void SetSize(int width, int height, mate::Arguments* args); + std::vector GetSize(); + void SetContentSize(int width, int height, mate::Arguments* args); + std::vector GetContentSize(); + void SetContentBounds(const gfx::Rect& bounds, mate::Arguments* args); + gfx::Rect GetContentBounds(); + void SetMinimumSize(int width, int height); + std::vector GetMinimumSize(); + void SetMaximumSize(int width, int height); + std::vector GetMaximumSize(); + void SetSheetOffset(double offsetY, mate::Arguments* args); + void SetResizable(bool resizable); + bool IsResizable(); + void SetMovable(bool movable); + #if defined(OS_WIN) || defined(OS_MACOSX) + void MoveTop(); + #endif + bool IsMovable(); + void SetMinimizable(bool minimizable); + bool IsMinimizable(); + void SetMaximizable(bool maximizable); + bool IsMaximizable(); + void SetFullScreenable(bool fullscreenable); + bool IsFullScreenable(); + void SetClosable(bool closable); + bool IsClosable(); + void SetAlwaysOnTop(bool top, mate::Arguments* args); + bool IsAlwaysOnTop(); + void Center(); + void SetPosition(int x, int y, mate::Arguments* args); + std::vector GetPosition(); + void SetTitle(const std::string& title); + std::string GetTitle(); + void FlashFrame(bool flash); + void SetSkipTaskbar(bool skip); + void SetSimpleFullScreen(bool simple_fullscreen); + bool IsSimpleFullScreen(); + void SetKiosk(bool kiosk); + bool IsKiosk(); + virtual void SetBackgroundColor(const std::string& color_name); + void SetHasShadow(bool has_shadow); + bool HasShadow(); + void SetOpacity(const double opacity); + double GetOpacity(); + void SetRepresentedFilename(const std::string& filename); + std::string GetRepresentedFilename(); + void SetDocumentEdited(bool edited); + bool IsDocumentEdited(); + void SetIgnoreMouseEvents(bool ignore, mate::Arguments* args); + void SetContentProtection(bool enable); + void SetFocusable(bool focusable); + void SetMenu(v8::Isolate* isolate, v8::Local menu); + void SetParentWindow(v8::Local value, mate::Arguments* args); + virtual void SetBrowserView(v8::Local value); + v8::Local GetNativeWindowHandle(); + void SetProgressBar(double progress, mate::Arguments* args); + void SetOverlayIcon(const gfx::Image& overlay, + const std::string& description); + void SetVisibleOnAllWorkspaces(bool visible); + bool IsVisibleOnAllWorkspaces(); + void SetAutoHideCursor(bool auto_hide); + virtual void SetVibrancy(mate::Arguments* args); + void SetTouchBar(const std::vector& items); + void RefreshTouchBarItem(const std::string& item_id); + void SetEscapeTouchBarItem(const mate::PersistentDictionary& item); + void SelectPreviousTab(); + void SelectNextTab(); + void MergeAllWindows(); + void MoveTabToNewWindow(); + void ToggleTabBar(); + void AddTabbedWindow(NativeWindow* window, mate::Arguments* args); + void SetAutoHideMenuBar(bool auto_hide); + bool IsMenuBarAutoHide(); + void SetMenuBarVisibility(bool visible); + bool IsMenuBarVisible(); + void SetAspectRatio(double aspect_ratio, mate::Arguments* args); + void PreviewFile(const std::string& path, mate::Arguments* args); + void CloseFilePreview(); + + // Public getters of NativeWindow. + v8::Local GetParentWindow() const; + std::vector> GetChildWindows() const; + v8::Local GetBrowserView() const; + bool IsModal() const; + + // Extra APIs added in JS. + bool SetThumbarButtons(mate::Arguments* args); +#if defined(TOOLKIT_VIEWS) + void SetIcon(mate::Handle icon); +#endif +#if defined(OS_WIN) + typedef base::Callback, + v8::Local)> MessageCallback; + bool HookWindowMessage(UINT message, const MessageCallback& callback); + bool IsWindowMessageHooked(UINT message); + void UnhookWindowMessage(UINT message); + void UnhookAllWindowMessages(); + bool SetThumbnailClip(const gfx::Rect& region); + bool SetThumbnailToolTip(const std::string& tooltip); + void SetAppDetails(const mate::Dictionary& options); +#endif + int32_t GetID() const; + + // Helpers. + + // Remove BrowserView. + void ResetBrowserView(); + + // Remove this window from parent window's |child_windows_|. + void RemoveFromParentChildWindows(); + +#if defined(OS_WIN) + typedef std::map MessageCallbackMap; + MessageCallbackMap messages_callback_map_; +#endif + + v8::Global browser_view_; + v8::Global menu_; + v8::Global parent_window_; + KeyWeakMap child_windows_; + + std::unique_ptr window_; + + base::WeakPtrFactory weak_factory_; +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_API_TOP_LEVEL_WINDOW_H_ diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 1be932a0b558..6c3b6796b272 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -29,6 +29,7 @@ #include "atom/browser/web_contents_zoom_controller.h" #include "atom/browser/web_view_guest_delegate.h" #include "atom/common/api/api_messages.h" +#include "atom/common/api/atom_api_native_image.h" #include "atom/common/api/event_emitter_caller.h" #include "atom/common/color_util.h" #include "atom/common/mouse_util.h" diff --git a/atom/browser/api/trackable_object.h b/atom/browser/api/trackable_object.h index 7decf3b077d9..cbe5e221fe74 100644 --- a/atom/browser/api/trackable_object.h +++ b/atom/browser/api/trackable_object.h @@ -107,7 +107,9 @@ class TrackableObject : public TrackableObjectBase, } protected: - TrackableObject() {} + TrackableObject() { + weak_map_id_ = ++next_id_; + } ~TrackableObject() override { RemoveFromWeakMap(); @@ -118,7 +120,6 @@ class TrackableObject : public TrackableObjectBase, if (!weak_map_) { weak_map_ = new atom::KeyWeakMap; } - weak_map_id_ = ++next_id_; weak_map_->Set(isolate, weak_map_id_, wrapper); } diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 41750c9cb23c..d9125b420f3c 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -46,6 +46,7 @@ V(atom_browser_render_process_preferences) \ V(atom_browser_session) \ V(atom_browser_system_preferences) \ + V(atom_browser_top_level_window) \ V(atom_browser_tray) \ V(atom_browser_web_contents) \ V(atom_browser_web_view_manager) \ diff --git a/filenames.gypi b/filenames.gypi index 05fb89b2129d..8b8dd7690bb9 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -152,6 +152,8 @@ 'atom/browser/api/atom_api_system_preferences.h', 'atom/browser/api/atom_api_system_preferences_mac.mm', 'atom/browser/api/atom_api_system_preferences_win.cc', + 'atom/browser/api/atom_api_top_level_window.cc', + 'atom/browser/api/atom_api_top_level_window.h', 'atom/browser/api/atom_api_tray.cc', 'atom/browser/api/atom_api_tray.h', 'atom/browser/api/atom_api_url_request.cc',