electron/atom/browser/api/atom_api_browser_window.cc

1339 lines
40 KiB
C++
Raw Normal View History

// Copyright (c) 2013 GitHub, Inc.
2014-04-25 09:49:37 +00:00
// 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_browser_window.h"
Implement initial, experimental BrowserView API Right now, `<webview>` is the only way to embed additional content in a `BrowserWindow`. Unfortunately `<webview>` suffers from a [number of problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20). To make matters worse, many of these are upstream Chromium bugs instead of Electron-specific bugs. For us at [Figma](https://www.figma.com), the main issue is very slow performance. Despite the upstream improvements to `<webview>` through the OOPIF work, it is probable that there will continue to be `<webview>`-specific bugs in the future. Therefore, this introduces a `<webview>` alternative to called `BrowserView`, which... - is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will likely also be bugs in `BrowserWindow` web contents) - is instantiated in the main process like `BrowserWindow` (and unlike `<webview>`, which lives in the DOM of a `BrowserWindow` web contents) - needs to be added to a `BrowserWindow` to display something on the screen This implements the most basic API. The API is expected to evolve and change in the near future and has consequently been marked as experimental. Please do not use this API in production unless you are prepared to deal with breaking changes. In the future, we will want to change the API to support multiple `BrowserView`s per window. We will also want to consider z-ordering auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
#include "atom/browser/api/atom_api_browser_view.h"
#include "atom/browser/api/atom_api_menu.h"
2014-04-24 08:45:25 +00:00
#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/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
2014-10-24 04:48:52 +00:00
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
2015-02-07 01:00:26 +00:00
#include "atom/common/native_mate_converters/image_converter.h"
2015-02-11 01:14:26 +00:00
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/options_switches.h"
2016-07-27 16:24:58 +00:00
#include "base/command_line.h"
2016-11-30 07:30:03 +00:00
#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"
2016-07-27 16:24:58 +00:00
#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"
2018-02-06 18:34:27 +00:00
#if defined(TOOLKIT_VIEWS)
#include "atom/browser/native_window_views.h"
#endif
2016-05-20 13:22:15 +00:00
#if defined(OS_WIN)
2015-08-06 03:10:34 +00:00
#include "atom/browser/ui/win/taskbar_host.h"
2016-11-12 16:59:57 +00:00
#include "ui/base/win/shell.h"
2015-08-06 03:10:34 +00:00
#endif
2016-09-06 08:24:37 +00:00
#include "atom/common/node_includes.h"
2015-08-06 03:10:34 +00:00
#if defined(OS_WIN)
namespace mate {
template<>
2015-08-06 03:10:34 +00:00
struct Converter<atom::TaskbarHost::ThumbarButton> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
2015-08-06 03:10:34 +00:00
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
2015-08-06 03:10:34 +00:00
#endif
namespace atom {
namespace api {
namespace {
// Converts binary data to Buffer.
2015-10-29 02:53:48 +00:00
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
auto buffer = node::Buffer::Copy(isolate, static_cast<char*>(val), size);
2015-10-29 02:53:48 +00:00
if (buffer.IsEmpty())
return v8::Null(isolate);
else
return buffer.ToLocalChecked();
}
} // namespace
BrowserWindow::BrowserWindow(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options)
: weak_factory_(this) {
mate::Handle<class WebContents> web_contents;
// Use options.webPreferences in WebContents.
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
// Copy the backgroundColor to webContents.
v8::Local<v8::Value> value;
if (options.Get(options::kBackgroundColor, &value))
web_preferences.Set(options::kBackgroundColor, value);
v8::Local<v8::Value> transparent;
if (options.Get("transparent", &transparent))
web_preferences.Set("transparent", transparent);
2017-06-26 09:13:05 +00:00
#if defined(ENABLE_OSR)
// Offscreen windows are always created frameless.
bool offscreen;
if (web_preferences.Get("offscreen", &offscreen) && offscreen) {
auto window_options = const_cast<mate::Dictionary&>(options);
window_options.Set(options::kFrame, false);
}
2017-06-26 09:13:05 +00:00
#endif
2016-12-20 22:43:52 +00:00
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
// render processes.
auto* existing_preferences =
WebContentsPreferences::FromWebContents(web_contents->web_contents());
base::DictionaryValue web_preferences_dict;
if (mate::ConvertFromV8(isolate, web_preferences.GetHandle(),
&web_preferences_dict)) {
existing_preferences->web_preferences()->Clear();
existing_preferences->Merge(web_preferences_dict);
}
} else {
// Creates the WebContents used by BrowserWindow.
web_contents = WebContents::Create(isolate, web_preferences);
}
Init(isolate, wrapper, options, web_contents);
}
void BrowserWindow::Init(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options,
mate::Handle<class WebContents> web_contents) {
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
2018-02-22 06:57:03 +00:00
api_web_contents_->AddObserver(this);
2018-02-23 00:15:13 +00:00
Observe(api_web_contents_->web_contents());
// Keep a copy of the options for later use.
mate::Dictionary(isolate, web_contents->GetWrapper()).Set(
"browserWindowOptions", options);
2016-06-19 03:06:08 +00:00
// The parent window.
mate::Handle<BrowserWindow> parent;
if (options.Get("parent", &parent) && !parent.IsEmpty())
2016-06-19 03:06:08 +00:00
parent_window_.Reset(isolate, parent.ToV8());
// Creates BrowserWindow.
2016-06-19 03:06:08 +00:00
window_.reset(NativeWindow::Create(
web_contents->managed_web_contents(),
options,
parent.IsEmpty() ? nullptr : parent->window_.get()));
web_contents->SetOwnerWindow(window_.get());
2017-11-13 07:13:54 +00:00
window_->set_is_offscreen_dummy(api_web_contents_->IsOffScreen());
2016-05-20 10:46:05 +00:00
// Tell the content module to initialize renderer widget with transparent
// mode.
ui::GpuSwitchingManager::SetTransparent(window_->transparent());
2016-05-20 13:22:15 +00:00
#if defined(TOOLKIT_VIEWS)
2016-05-20 10:46:05 +00:00
// Sets the window icon.
mate::Handle<NativeImage> icon;
if (options.Get(options::kIcon, &icon) && !icon.IsEmpty())
2016-05-20 13:22:15 +00:00
SetIcon(icon);
2016-05-20 10:46:05 +00:00
#endif
2016-07-02 07:16:47 +00:00
window_->InitFromOptions(options);
window_->AddObserver(this);
InitWith(isolate, wrapper);
2016-07-02 07:16:47 +00:00
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);
auto* host = web_contents->web_contents()->GetRenderViewHost();
if (host)
host->GetWidget()->AddInputEventObserver(this);
}
BrowserWindow::~BrowserWindow() {
if (!window_->IsClosed())
window_->CloseImmediately();
2018-02-22 06:57:03 +00:00
api_web_contents_->RemoveObserver(this);
// Destroy the native window in next tick because the native code might be
// iterating all windows.
2016-11-30 07:30:03 +00:00
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release());
}
void BrowserWindow::OnInputEvent(const blink::WebInputEvent& event) {
switch (event.GetType()) {
case blink::WebInputEvent::kGestureScrollBegin:
case blink::WebInputEvent::kGestureScrollUpdate:
case blink::WebInputEvent::kGestureScrollEnd:
Emit("scroll-touch-edge");
break;
default:
break;
}
}
void BrowserWindow::RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) {
if (old_host)
old_host->GetWidget()->RemoveInputEventObserver(this);
if (new_host)
new_host->GetWidget()->AddInputEventObserver(this);
}
void BrowserWindow::RenderViewCreated(
content::RenderViewHost* render_view_host) {
if (!window_->transparent())
return;
content::RenderWidgetHostImpl* impl = content::RenderWidgetHostImpl::FromID(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
if (impl)
impl->SetBackgroundOpaque(false);
}
void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
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());
// Emit the ReadyToShow event in next tick in case of pending drawing work.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind([](base::WeakPtr<BrowserWindow> self) {
2018-02-22 06:10:33 +00:00
if (self)
self->Emit("ready-to-show");
}, GetWeakPtr()));
}
void BrowserWindow::BeforeUnloadDialogCancelled() {
WindowList::WindowCloseCancelled(window_.get());
// Cancel unresponsive event when window close is cancelled.
2018-02-23 00:15:13 +00:00
window_unresponsive_closure_.Cancel();
}
void BrowserWindow::OnRendererUnresponsive(content::RenderWidgetHost*) {
// Schedule the unresponsive shortly later, since we may receive the
// responsive event soon. This could happen after the whole application had
// blocked for a while.
// Also notice that when closing this event would be ignored because we have
// explicitly started a close timeout counter. This is on purpose because we
// don't want the unresponsive event to be sent too early when user is closing
// the window.
ScheduleUnresponsiveEvent(50);
}
bool BrowserWindow::OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* rfh) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(BrowserWindow, message, rfh)
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_UpdateDraggableRegions,
UpdateDraggableRegions)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void BrowserWindow::OnCloseContents() {
if (!web_contents())
return;
Observe(nullptr);
// Close all child windows before closing current window.
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
for (v8::Local<v8::Value> value : child_windows_.Values(isolate())) {
mate::Handle<BrowserWindow> child;
if (mate::ConvertFromV8(isolate(), value, &child) && !child.IsEmpty())
child->window_->CloseImmediately();
}
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// 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();
// Do not sent "unresponsive" event after window is closed.
2018-02-23 00:15:13 +00:00
window_unresponsive_closure_.Cancel();
}
void BrowserWindow::OnRendererResponsive() {
2018-02-23 00:15:13 +00:00
window_unresponsive_closure_.Cancel();
Emit("responsive");
}
void BrowserWindow::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close");
}
void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
// When user tries to close the window by clicking the close button, we do
// not close the window immediately, instead we try to close the web page
// first, and when the web page is closed the window will also be closed.
*prevent_default = true;
// Assume the window is not responding if it doesn't cancel the close and is
// not closed in 5s, in this way we can quickly show the unresponsive
// dialog when the window is busy executing some script withouth waiting for
// the unresponsive timeout.
2018-02-23 00:15:13 +00:00
if (window_unresponsive_closure_.IsCancelled())
ScheduleUnresponsiveEvent(5000);
if (!web_contents())
// Already closed by renderer
return;
if (web_contents()->NeedToFireBeforeUnload())
web_contents()->DispatchBeforeUnload();
else
web_contents()->Close();
}
void BrowserWindow::OnWindowClosed() {
api_web_contents_->DestroyWebContents(true /* async */);
2015-06-24 09:58:12 +00:00
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");
2016-06-17 07:57:03 +00:00
RemoveFromParentChildWindows();
ResetBrowserView();
// Destroy the native class when window is closed.
2016-11-30 07:30:03 +00:00
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, GetDestroyClosure());
}
void BrowserWindow::OnWindowEndSession() {
Emit("session-end");
2017-04-21 20:45:30 +00:00
}
void BrowserWindow::OnWindowBlur() {
2013-05-24 09:58:39 +00:00
Emit("blur");
}
void BrowserWindow::OnWindowFocus() {
Emit("focus");
}
void BrowserWindow::OnWindowShow() {
Emit("show");
}
void BrowserWindow::OnWindowHide() {
Emit("hide");
}
void BrowserWindow::OnWindowMaximize() {
2014-11-25 04:43:25 +00:00
Emit("maximize");
}
void BrowserWindow::OnWindowUnmaximize() {
2014-11-25 04:43:25 +00:00
Emit("unmaximize");
}
void BrowserWindow::OnWindowMinimize() {
2014-11-25 04:43:25 +00:00
Emit("minimize");
}
void BrowserWindow::OnWindowRestore() {
2014-11-25 04:43:25 +00:00
Emit("restore");
}
void BrowserWindow::OnWindowResize() {
2015-05-09 18:03:16 +00:00
Emit("resize");
2015-05-09 15:55:10 +00:00
}
void BrowserWindow::OnWindowMove() {
2015-05-09 18:03:16 +00:00
Emit("move");
2015-05-09 15:55:10 +00:00
}
void BrowserWindow::OnWindowMoved() {
2015-05-20 08:37:13 +00:00
Emit("moved");
}
void BrowserWindow::OnWindowEnterFullScreen() {
2014-11-25 04:43:25 +00:00
Emit("enter-full-screen");
}
void BrowserWindow::OnWindowLeaveFullScreen() {
2014-11-25 04:43:25 +00:00
Emit("leave-full-screen");
}
void BrowserWindow::OnWindowScrollTouchBegin() {
2016-01-22 00:31:09 +00:00
Emit("scroll-touch-begin");
}
void BrowserWindow::OnWindowScrollTouchEnd() {
2016-01-22 00:31:09 +00:00
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) {
2015-06-25 16:25:55 +00:00
Emit("app-command", command_name);
2015-06-18 00:31:50 +00:00
}
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");
}
2015-10-27 01:12:01 +00:00
#if defined(OS_WIN)
void BrowserWindow::OnWindowMessage(UINT message,
WPARAM w_param,
LPARAM l_param) {
if (IsWindowMessageHooked(message)) {
messages_callback_map_[message].Run(
2015-10-29 02:53:48 +00:00
ToBuffer(isolate(), static_cast<void*>(&w_param), sizeof(WPARAM)),
ToBuffer(isolate(), static_cast<void*>(&l_param), sizeof(LPARAM)));
}
2015-10-27 01:12:01 +00:00
}
#endif
// static
mate::WrappableBase* BrowserWindow::New(mate::Arguments* args) {
2015-03-26 03:34:41 +00:00
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();
}
void BrowserWindow::Focus() {
window_->Focus(true);
2013-05-16 14:56:52 +00:00
}
void BrowserWindow::Blur() {
2016-03-11 05:45:51 +00:00
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;
2014-10-17 14:51:20 +00:00
window_->ShowInactive();
}
void BrowserWindow::Hide() {
window_->Hide();
2013-10-03 00:27:59 +00:00
}
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() {
2014-05-14 21:58:49 +00:00
return window_->IsMaximized();
}
void BrowserWindow::Minimize() {
window_->Minimize();
}
void BrowserWindow::Restore() {
window_->Restore();
}
bool BrowserWindow::IsMinimized() {
2014-07-26 05:58:26 +00:00
return window_->IsMinimized();
}
void BrowserWindow::SetFullScreen(bool fullscreen) {
2014-11-25 06:34:14 +00:00
window_->SetFullScreen(fullscreen);
}
bool BrowserWindow::IsFullscreen() {
return window_->IsFullscreen();
}
void BrowserWindow::SetBounds(const gfx::Rect& bounds, mate::Arguments* args) {
2016-01-15 04:54:12 +00:00
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) {
2016-08-04 19:02:24 +00:00
bool animate = false;
args->GetNext(&animate);
window_->SetContentBounds(bounds, animate);
}
gfx::Rect BrowserWindow::GetContentBounds() {
2016-07-29 01:19:17 +00:00
return window_->GetContentBounds();
}
void BrowserWindow::SetSize(int width, int height, mate::Arguments* args) {
2016-01-15 04:54:12 +00:00
bool animate = false;
args->GetNext(&animate);
2016-01-15 04:54:12 +00:00
window_->SetSize(gfx::Size(width, height), animate);
}
std::vector<int> BrowserWindow::GetSize() {
std::vector<int> 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) {
2016-01-15 04:54:12 +00:00
bool animate = false;
args->GetNext(&animate);
2016-01-15 04:54:12 +00:00
window_->SetContentSize(gfx::Size(width, height), animate);
2014-05-15 08:05:35 +00:00
}
std::vector<int> BrowserWindow::GetContentSize() {
2014-05-15 07:30:04 +00:00
std::vector<int> 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));
2013-04-18 07:38:04 +00:00
}
std::vector<int> BrowserWindow::GetMinimumSize() {
std::vector<int> 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));
2013-04-18 07:38:04 +00:00
}
std::vector<int> BrowserWindow::GetMaximumSize() {
std::vector<int> 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);
2016-04-19 05:45:38 +00:00
}
void BrowserWindow::SetResizable(bool resizable) {
window_->SetResizable(resizable);
2013-04-18 07:38:04 +00:00
}
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) {
2016-01-22 21:24:33 +00:00
window_->SetMaximizable(maximizable);
}
bool BrowserWindow::IsMaximizable() {
2016-01-22 21:24:33 +00:00
return window_->IsMaximizable();
}
void BrowserWindow::SetFullScreenable(bool fullscreenable) {
2016-01-23 07:47:37 +00:00
window_->SetFullScreenable(fullscreenable);
2016-01-22 21:24:33 +00:00
}
bool BrowserWindow::IsFullScreenable() {
2016-01-23 07:47:37 +00:00
return window_->IsFullScreenable();
2016-01-22 21:24:33 +00:00
}
void BrowserWindow::SetClosable(bool closable) {
window_->SetClosable(closable);
}
bool BrowserWindow::IsClosable() {
return window_->IsClosable();
}
void BrowserWindow::SetAlwaysOnTop(bool top, mate::Arguments* args) {
2016-09-22 02:49:06 +00:00
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);
}
2013-04-18 07:38:04 +00:00
}
bool BrowserWindow::IsAlwaysOnTop() {
return window_->IsAlwaysOnTop();
}
void BrowserWindow::Center() {
window_->Center();
}
void BrowserWindow::SetPosition(int x, int y, mate::Arguments* args) {
2016-01-15 04:54:12 +00:00
bool animate = false;
args->GetNext(&animate);
2016-01-15 04:54:12 +00:00
window_->SetPosition(gfx::Point(x, y), animate);
}
std::vector<int> BrowserWindow::GetPosition() {
std::vector<int> result(2);
gfx::Point pos = window_->GetPosition();
result[0] = pos.x();
result[1] = pos.y();
return result;
}
void BrowserWindow::SetTitle(const std::string& title) {
window_->SetTitle(title);
2013-04-18 06:30:05 +00:00
}
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();
}
void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
2015-10-23 03:35:33 +00:00
window_->SetBackgroundColor(color_name);
}
void BrowserWindow::SetHasShadow(bool has_shadow) {
window_->SetHasShadow(has_shadow);
}
bool BrowserWindow::HasShadow() {
return window_->HasShadow();
}
void BrowserWindow::SetOpacity(const double opacity) {
2017-09-29 02:26:02 +00:00
window_->SetOpacity(opacity);
}
double BrowserWindow::GetOpacity() {
return window_->GetOpacity();
}
void BrowserWindow::FocusOnWebView() {
window_->FocusOnWebView();
}
void BrowserWindow::BlurWebView() {
window_->BlurWebView();
}
bool BrowserWindow::IsWebViewFocused() {
return window_->IsWebViewFocused();
}
2013-11-22 06:23:19 +00:00
void BrowserWindow::SetRepresentedFilename(const std::string& filename) {
2014-08-21 13:00:49 +00:00
window_->SetRepresentedFilename(filename);
}
std::string BrowserWindow::GetRepresentedFilename() {
2014-08-21 13:00:49 +00:00
return window_->GetRepresentedFilename();
}
void BrowserWindow::SetDocumentEdited(bool edited) {
2014-08-21 13:00:49 +00:00
window_->SetDocumentEdited(edited);
}
bool BrowserWindow::IsDocumentEdited() {
2014-08-21 13:00:49 +00:00
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) {
2016-06-13 08:10:28 +00:00
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);
2014-09-17 01:42:47 +00:00
}
void BrowserWindow::SetOverlayIcon(const gfx::Image& overlay,
2015-02-11 01:14:26 +00:00
const std::string& description) {
2015-02-07 01:07:29 +00:00
window_->SetOverlayIcon(overlay, description);
}
bool BrowserWindow::SetThumbarButtons(mate::Arguments* args) {
2015-08-06 03:10:34 +00:00
#if defined(OS_WIN)
std::vector<TaskbarHost::ThumbarButton> buttons;
if (!args->GetNext(&buttons)) {
args->ThrowError();
2015-08-06 04:44:07 +00:00
return false;
2015-08-06 03:10:34 +00:00
}
auto window = static_cast<NativeWindowViews*>(window_.get());
2015-08-06 04:44:07 +00:00
return window->taskbar_host().SetThumbarButtons(
window_->GetAcceleratedWidget(), buttons);
2015-08-06 04:44:07 +00:00
#else
return false;
2015-08-06 03:10:34 +00:00
#endif
}
void BrowserWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
2015-06-24 11:51:11 +00:00
mate::Handle<Menu> menu;
if (value->IsObject() &&
mate::V8ToString(value->ToObject()->GetConstructorName()) == "Menu" &&
mate::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) {
2015-06-24 11:51:11 +00:00
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) {
2014-11-12 12:31:55 +00:00
window_->SetAutoHideMenuBar(auto_hide);
}
bool BrowserWindow::IsMenuBarAutoHide() {
2014-11-12 12:31:55 +00:00
return window_->IsMenuBarAutoHide();
}
void BrowserWindow::SetMenuBarVisibility(bool visible) {
2014-11-12 12:31:55 +00:00
window_->SetMenuBarVisibility(visible);
}
bool BrowserWindow::IsMenuBarVisible() {
2014-11-12 12:31:55 +00:00
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();
}
2016-07-14 20:27:16 +00:00
bool BrowserWindow::SetThumbnailClip(const gfx::Rect& region) {
2016-07-14 20:27:16 +00:00
auto window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbnailClip(
window_->GetAcceleratedWidget(), region);
}
bool BrowserWindow::SetThumbnailToolTip(const std::string& tooltip) {
auto window = static_cast<NativeWindowViews*>(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;
2016-11-28 22:26:30 +00:00
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
2016-05-20 13:22:15 +00:00
#if defined(TOOLKIT_VIEWS)
void BrowserWindow::SetIcon(mate::Handle<NativeImage> icon) {
2016-05-20 13:22:15 +00:00
#if defined(OS_WIN)
static_cast<NativeWindowViews*>(window_.get())->SetIcon(
icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
icon->GetHICON(GetSystemMetrics(SM_CXICON)));
2016-05-20 13:22:15 +00:00
#elif defined(USE_X11)
static_cast<NativeWindowViews*>(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) {
2016-10-26 00:47:22 +00:00
std::string display_name;
2016-10-26 00:55:34 +00:00
if (!args->GetNext(&display_name))
2016-10-26 00:47:22 +00:00
display_name = path;
window_->PreviewFile(path, display_name);
2016-10-12 01:08:01 +00:00
}
void BrowserWindow::CloseFilePreview() {
2016-11-21 18:30:13 +00:00
window_->CloseFilePreview();
}
void BrowserWindow::SetParentWindow(v8::Local<v8::Value> value,
2016-06-17 07:57:03 +00:00
mate::Arguments* args) {
if (IsModal()) {
args->ThrowError("Can not be called for modal window");
return;
}
mate::Handle<BrowserWindow> parent;
if (value->IsNull() || value->IsUndefined()) {
2016-06-17 07:57:03 +00:00
RemoveFromParentChildWindows();
parent_window_.Reset();
window_->SetParentWindow(nullptr);
} else if (mate::ConvertFromV8(isolate(), value, &parent)) {
2016-06-17 07:09:43 +00:00
parent_window_.Reset(isolate(), value);
2016-06-17 07:57:03 +00:00
window_->SetParentWindow(parent->window_.get());
parent->child_windows_.Set(isolate(), ID(), GetWrapper());
2016-06-17 07:09:43 +00:00
} else {
args->ThrowError("Must pass BrowserWindow instance or null");
}
}
v8::Local<v8::Value> BrowserWindow::GetParentWindow() const {
2016-06-17 07:09:43 +00:00
if (parent_window_.IsEmpty())
return v8::Null(isolate());
else
return v8::Local<v8::Value>::New(isolate(), parent_window_);
}
std::vector<v8::Local<v8::Object>> BrowserWindow::GetChildWindows() const {
2016-06-17 07:57:03 +00:00
return child_windows_.Values(isolate());
}
v8::Local<v8::Value> BrowserWindow::GetBrowserView() const {
Implement initial, experimental BrowserView API Right now, `<webview>` is the only way to embed additional content in a `BrowserWindow`. Unfortunately `<webview>` suffers from a [number of problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20). To make matters worse, many of these are upstream Chromium bugs instead of Electron-specific bugs. For us at [Figma](https://www.figma.com), the main issue is very slow performance. Despite the upstream improvements to `<webview>` through the OOPIF work, it is probable that there will continue to be `<webview>`-specific bugs in the future. Therefore, this introduces a `<webview>` alternative to called `BrowserView`, which... - is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will likely also be bugs in `BrowserWindow` web contents) - is instantiated in the main process like `BrowserWindow` (and unlike `<webview>`, which lives in the DOM of a `BrowserWindow` web contents) - needs to be added to a `BrowserWindow` to display something on the screen This implements the most basic API. The API is expected to evolve and change in the near future and has consequently been marked as experimental. Please do not use this API in production unless you are prepared to deal with breaking changes. In the future, we will want to change the API to support multiple `BrowserView`s per window. We will also want to consider z-ordering auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
if (browser_view_.IsEmpty()) {
return v8::Null(isolate());
}
return v8::Local<v8::Value>::New(isolate(), browser_view_);
}
void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
ResetBrowserView();
Implement initial, experimental BrowserView API Right now, `<webview>` is the only way to embed additional content in a `BrowserWindow`. Unfortunately `<webview>` suffers from a [number of problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20). To make matters worse, many of these are upstream Chromium bugs instead of Electron-specific bugs. For us at [Figma](https://www.figma.com), the main issue is very slow performance. Despite the upstream improvements to `<webview>` through the OOPIF work, it is probable that there will continue to be `<webview>`-specific bugs in the future. Therefore, this introduces a `<webview>` alternative to called `BrowserView`, which... - is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will likely also be bugs in `BrowserWindow` web contents) - is instantiated in the main process like `BrowserWindow` (and unlike `<webview>`, which lives in the DOM of a `BrowserWindow` web contents) - needs to be added to a `BrowserWindow` to display something on the screen This implements the most basic API. The API is expected to evolve and change in the near future and has consequently been marked as experimental. Please do not use this API in production unless you are prepared to deal with breaking changes. In the future, we will want to change the API to support multiple `BrowserView`s per window. We will also want to consider z-ordering auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
mate::Handle<BrowserView> browser_view;
if (value->IsNull() || value->IsUndefined()) {
Implement initial, experimental BrowserView API Right now, `<webview>` is the only way to embed additional content in a `BrowserWindow`. Unfortunately `<webview>` suffers from a [number of problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20). To make matters worse, many of these are upstream Chromium bugs instead of Electron-specific bugs. For us at [Figma](https://www.figma.com), the main issue is very slow performance. Despite the upstream improvements to `<webview>` through the OOPIF work, it is probable that there will continue to be `<webview>`-specific bugs in the future. Therefore, this introduces a `<webview>` alternative to called `BrowserView`, which... - is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will likely also be bugs in `BrowserWindow` web contents) - is instantiated in the main process like `BrowserWindow` (and unlike `<webview>`, which lives in the DOM of a `BrowserWindow` web contents) - needs to be added to a `BrowserWindow` to display something on the screen This implements the most basic API. The API is expected to evolve and change in the near future and has consequently been marked as experimental. Please do not use this API in production unless you are prepared to deal with breaking changes. In the future, we will want to change the API to support multiple `BrowserView`s per window. We will also want to consider z-ordering auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
window_->SetBrowserView(nullptr);
} else if (mate::ConvertFromV8(isolate(), value, &browser_view)) {
window_->SetBrowserView(browser_view->view());
browser_view->web_contents()->SetOwnerWindow(window_.get());
Implement initial, experimental BrowserView API Right now, `<webview>` is the only way to embed additional content in a `BrowserWindow`. Unfortunately `<webview>` suffers from a [number of problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20). To make matters worse, many of these are upstream Chromium bugs instead of Electron-specific bugs. For us at [Figma](https://www.figma.com), the main issue is very slow performance. Despite the upstream improvements to `<webview>` through the OOPIF work, it is probable that there will continue to be `<webview>`-specific bugs in the future. Therefore, this introduces a `<webview>` alternative to called `BrowserView`, which... - is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will likely also be bugs in `BrowserWindow` web contents) - is instantiated in the main process like `BrowserWindow` (and unlike `<webview>`, which lives in the DOM of a `BrowserWindow` web contents) - needs to be added to a `BrowserWindow` to display something on the screen This implements the most basic API. The API is expected to evolve and change in the near future and has consequently been marked as experimental. Please do not use this API in production unless you are prepared to deal with breaking changes. In the future, we will want to change the API to support multiple `BrowserView`s per window. We will also want to consider z-ordering auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
browser_view_.Reset(isolate(), value);
}
}
void BrowserWindow::ResetBrowserView() {
if (browser_view_.IsEmpty()) {
return;
}
mate::Handle<BrowserView> 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<v8::Value> BrowserWindow::GetNativeWindowHandle() {
2016-01-07 20:38:35 +00:00
gfx::AcceleratedWidget handle = window_->GetAcceleratedWidget();
return ToBuffer(
isolate(), static_cast<void*>(&handle), sizeof(gfx::AcceleratedWidget));
2016-01-07 20:38:35 +00:00
}
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();
}
2018-02-27 06:25:09 +00:00
void BrowserWindow::AddTabbedWindow(NativeWindow* window,
2018-02-28 08:22:42 +00:00
mate::Arguments* args) {
const bool windowAdded = window_->AddTabbedWindow(window);
if (!windowAdded)
2018-02-28 08:22:42 +00:00
args->ThrowError("AddTabbedWindow cannot be called by a window on itself.");
}
void BrowserWindow::SetVibrancy(mate::Arguments* args) {
std::string type;
2016-11-07 20:22:41 +00:00
args->GetNext(&type);
window_->SetVibrancy(type);
2016-11-07 20:22:41 +00:00
}
void BrowserWindow::SetTouchBar(
const std::vector<mate::PersistentDictionary>& items) {
window_->SetTouchBar(items);
}
void BrowserWindow::RefreshTouchBarItem(const std::string& item_id) {
2017-03-01 00:08:12 +00:00
window_->RefreshTouchBarItem(item_id);
}
void BrowserWindow::SetEscapeTouchBarItem(
const mate::PersistentDictionary& item) {
window_->SetEscapeTouchBarItem(item);
}
int32_t BrowserWindow::ID() const {
2015-06-24 08:37:48 +00:00
return weak_map_id();
}
v8::Local<v8::Value> BrowserWindow::WebContents(v8::Isolate* isolate) {
Implement initial, experimental BrowserView API Right now, `<webview>` is the only way to embed additional content in a `BrowserWindow`. Unfortunately `<webview>` suffers from a [number of problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20). To make matters worse, many of these are upstream Chromium bugs instead of Electron-specific bugs. For us at [Figma](https://www.figma.com), the main issue is very slow performance. Despite the upstream improvements to `<webview>` through the OOPIF work, it is probable that there will continue to be `<webview>`-specific bugs in the future. Therefore, this introduces a `<webview>` alternative to called `BrowserView`, which... - is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will likely also be bugs in `BrowserWindow` web contents) - is instantiated in the main process like `BrowserWindow` (and unlike `<webview>`, which lives in the DOM of a `BrowserWindow` web contents) - needs to be added to a `BrowserWindow` to display something on the screen This implements the most basic API. The API is expected to evolve and change in the near future and has consequently been marked as experimental. Please do not use this API in production unless you are prepared to deal with breaking changes. In the future, we will want to change the API to support multiple `BrowserView`s per window. We will also want to consider z-ordering auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
if (web_contents_.IsEmpty()) {
return v8::Null(isolate);
Implement initial, experimental BrowserView API Right now, `<webview>` is the only way to embed additional content in a `BrowserWindow`. Unfortunately `<webview>` suffers from a [number of problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20). To make matters worse, many of these are upstream Chromium bugs instead of Electron-specific bugs. For us at [Figma](https://www.figma.com), the main issue is very slow performance. Despite the upstream improvements to `<webview>` through the OOPIF work, it is probable that there will continue to be `<webview>`-specific bugs in the future. Therefore, this introduces a `<webview>` alternative to called `BrowserView`, which... - is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will likely also be bugs in `BrowserWindow` web contents) - is instantiated in the main process like `BrowserWindow` (and unlike `<webview>`, which lives in the DOM of a `BrowserWindow` web contents) - needs to be added to a `BrowserWindow` to display something on the screen This implements the most basic API. The API is expected to evolve and change in the near future and has consequently been marked as experimental. Please do not use this API in production unless you are prepared to deal with breaking changes. In the future, we will want to change the API to support multiple `BrowserView`s per window. We will also want to consider z-ordering auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
}
return v8::Local<v8::Value>::New(isolate, web_contents_);
2014-04-24 08:45:25 +00:00
}
void BrowserWindow::RemoveFromParentChildWindows() {
2016-06-17 07:57:03 +00:00
if (parent_window_.IsEmpty())
return;
mate::Handle<BrowserWindow> parent;
if (!mate::ConvertFromV8(isolate(), GetParentWindow(), &parent)
|| parent.IsEmpty()) {
return;
}
parent->child_windows_.Remove(ID());
2016-06-17 07:57:03 +00:00
}
void BrowserWindow::UpdateDraggableRegions(
content::RenderFrameHost* rfh,
const std::vector<DraggableRegion>& regions) {
window_->UpdateDraggableRegions(regions);
}
void BrowserWindow::ScheduleUnresponsiveEvent(int ms) {
2018-02-23 00:15:13 +00:00
if (!window_unresponsive_closure_.IsCancelled())
return;
2018-02-23 00:15:13 +00:00
window_unresponsive_closure_.Reset(
base::Bind(&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr()));
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
2018-02-23 00:15:13 +00:00
window_unresponsive_closure_.callback(),
base::TimeDelta::FromMilliseconds(ms));
}
void BrowserWindow::NotifyWindowUnresponsive() {
2018-02-23 00:15:13 +00:00
window_unresponsive_closure_.Cancel();
if (!window_->IsClosed() && window_->IsEnabled() &&
!IsUnresponsiveEventSuppressed()) {
Emit("unresponsive");
}
}
// static
void BrowserWindow::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
2016-08-02 10:28:12 +00:00
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)
.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
2016-05-20 13:22:15 +00:00
#if defined(TOOLKIT_VIEWS)
.SetMethod("setIcon", &BrowserWindow::SetIcon)
#endif
.SetProperty("id", &BrowserWindow::ID)
.SetProperty("webContents", &BrowserWindow::WebContents);
2013-04-18 16:06:10 +00:00
}
2015-10-01 05:45:59 +00:00
// static
v8::Local<v8::Value> BrowserWindow::From(v8::Isolate* isolate,
NativeWindow* native_window) {
2015-10-01 05:45:59 +00:00
auto existing = TrackableObject::FromWrappedClass(isolate, native_window);
if (existing)
return existing->GetWrapper();
2015-10-01 05:45:59 +00:00
else
return v8::Null(isolate);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::BrowserWindow;
2015-06-24 08:37:48 +00:00
2015-05-22 11:11:22 +00:00
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
BrowserWindow::SetConstructor(isolate, base::Bind(&BrowserWindow::New));
2016-08-02 08:02:04 +00:00
mate::Dictionary browser_window(
isolate, BrowserWindow::GetConstructor(isolate)->GetFunction());
browser_window.SetMethod(
"fromId",
&mate::TrackableObject<BrowserWindow>::FromWeakMapID);
browser_window.SetMethod(
"getAllWindows",
&mate::TrackableObject<BrowserWindow>::GetAll);
2015-06-24 08:37:48 +00:00
2014-06-28 11:49:55 +00:00
mate::Dictionary dict(isolate, exports);
2015-06-24 08:37:48 +00:00
dict.Set("BrowserWindow", browser_window);
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)