electron/shell/browser/api/electron_api_base_window.cc
electron-roller[bot] 3e12da8ed1
chore: bump chromium to 142.0.7444.23 (39-x-y) (#48307)
* chore: bump chromium in DEPS to 142.0.7432.2

* chore: bump chromium in DEPS to 142.0.7434.1

* chore: bump chromium in DEPS to 142.0.7436.1

* chore: bump chromium in DEPS to 142.0.7438.1

* chore: bump chromium in DEPS to 142.0.7440.1

* chore: bump chromium in DEPS to 142.0.7442.1

* chore: bump chromium in DEPS to 142.0.7444.1

* chore: bump chromium in DEPS to 142.0.7444.6

* chore: bump chromium in DEPS to 142.0.7444.3

* 6973697: Use type tags for data stored in V8 internal fields

https://chromium-review.googlesource.com/c/chromium/src/+/6973697

* chore: update patches

* chore: update filenames.libcxx.gni

* fix: parse macOS SDK version across line break
https://chromium-review.googlesource.com/c/chromium/src/+/6980166

(cherry picked from commit 2bcbb33de04fa13e7c923b2420f89c3846f5988b)

* fix: replace v8::Object::SetPrototype() usage
https://chromium-review.googlesource.com/c/v8/v8/+/6983465
https://github.com/nodejs/node/pull/55453

(cherry picked from commit c31b9ed5ac84bbd111c72273d9334af6c50ed374)

* fix: replace additional usages of SetPrototype
https://chromium-review.googlesource.com/c/v8/v8/+/6983465

(cherry picked from commit bf151e9d28520c7dd74cba62240acbcaaab5433d)

* fixup! fix: replace additional usages of SetPrototype https://chromium-review.googlesource.com/c/v8/v8/+/6983465

(cherry picked from commit f4434755b82b098e4d83d42bab26f183b6824f99)

* build: use macos 15 minimum
https://chromium-review.googlesource.com/c/chromium/src/+/6980166

(cherry picked from commit 4d2b5d7b2cf9a1786cdb1a77bf73e4ad0d3e45d1)

* fixup! build: use macos 15 minimum https://chromium-review.googlesource.com/c/chromium/src/+/6980166

(cherry picked from commit 94bb41a66330dcaf6b92c80cfefd72759405793d)

* ci: ignore missing dir for strip_universal_deep

(cherry picked from commit 634963f171bc5f6050151f76973e7ffbab0e00cf)

* chore: update patches

* chore: update patches

* chore: bump chromium in DEPS to 142.0.7444.23

* fix: disable C++ modules in electron_lib builds
https://chromium-review.googlesource.com/c/chromium/src/+/6950738

(cherry picked from commit 6207c79aecae04675b1e258ec14025c3ddfdf270)

* Revert "build: use macos 15 minimum"

This reverts commit 2fc12d6acc1b24f3cbd0adb03122bf6b21eb14b9.

Initially this change was made to test if it fixes libcxx
compilation issues. As that's now resolved by disabling libcxx
modules, this can be reverted.

(cherry picked from commit ad52007d5baffc3da65c0a994943f25da0c3f1c2)

* fix: js2c compilation failure

https://chromium-review.googlesource.com/c/chromium/src/+/6950738

See patch description explaining MacOS 26 SDK headers incompatibility.

(cherry picked from commit 39e2470875cdbf20b86c30ee2c5caa8845465434)

* fix: disable C++ modules in libnode builds

(cherry picked from commit fd0a7b61a151c92729da41eba63fb7ee5b0beebc)

* fixup! fix: replace v8::Object::SetPrototype() usage https://chromium-review.googlesource.com/c/v8/v8/+/6983465 https://github.com/nodejs/node/pull/55453

(cherry picked from commit 2f52159b71ee4aa779dfd3e3050f3b09c2664c36)

* build: switch to macos-15 runner

build/mac/find_sdk.py now requires macOS 15 SDK as a minimum version. The
macos 15 runners default to an Xcode using the 15 SDK and removes older
versions.

(cherry picked from commit e368703f24577e73d904c684a0b4ae53bacfaef2)

* chore: update patches

* fix: partially revert is_headless_mode removal
https://chromium-review.googlesource.com/c/chromium/src/+/6955633

This patch should likely be reworked. For now, this partially reverts the
removal of a required class property to restore behavior.

(cherry picked from commit aff3bf9a244608863bc96b3e2aef911158b29574)

* 6938086: Rename native_widget_types.h -> native_ui_types.h | https://chromium-review.googlesource.com/c/chromium/src/+/6938086

(cherry picked from commit c95ac7bf2b1eda493167b8e36c59d70d86d51429)

* 6973697: Use type tags for data stored in V8 internal fields

https://chromium-review.googlesource.com/c/chromium/src/+/6973697

* fixup! fix: check new forced colors enum value https://chromium-review.googlesource.com/c/chromium/src/+/6944403

(cherry picked from commit 0829c74b2fbcdf03ca462b4b0b76efd727d3d891)

* fix: check new forced colors enum value
https://chromium-review.googlesource.com/c/chromium/src/+/6944403

(cherry picked from commit d5858798074719d19d041fa291c3fd1af8d17f5d)

* feat: add new memory-eviction exit reason
https://chromium-review.googlesource.com/c/chromium/src/+/6991933

(cherry picked from commit 6e63197a2292aece65cd52b7b849d3ff3d10bb90)

* fix: views::NonClientFrameView -> views::FrameView
https://chromium-review.googlesource.com/c/chromium/src/+/7005027
https://chromium-review.googlesource.com/c/chromium/src/+/6966937

(cherry picked from commit 1e86b6ddfb2d19b5bfe30e7539f0a377ffa907ab)

* fix: migrate NetworkConditions -> MatchedNetworkConditions
https://chromium-review.googlesource.com/c/chromium/src/+/6827307

(cherry picked from commit 97100ac1682053d3447e63ed5f03dc2d9938e6ca)

* fix: provide DeviceEmulationCacheBehavior param
https://chromium-review.googlesource.com/c/chromium/src/+/6965238

(cherry picked from commit f9a08c53846ab269c57c14eae6b1c03b163fb30c)

* fix: add missing image_skia include
https://chromium-review.googlesource.com/c/chromium/src/+/6986762

(cherry picked from commit dd5eaf03fd7fbfd49afbe3259c5bf036be566bd9)

* fixup! fix: add missing image_skia include https://chromium-review.googlesource.com/c/chromium/src/+/6986762

(cherry picked from commit 249c4d4de1df4d1588d6fa6fcf5f33b43a6c0f62)

* 6948286: [wasm-imported-strings] Drop feature flag

https://chromium-review.googlesource.com/c/v8/v8/+/6948286

* fix: disable protocol handler DCHECK

https://chromium-review.googlesource.com/c/chromium/src/+/6727594

Ignore the extension custom protocol handler registry DCHECK until
we invest in supporting it. Replacing this DCHECK seems harmless
and will unblock the roll.

(cherry picked from commit 019d3f0b09aeff8aed7991d9669a4ba7f265808b)

* 6986762: Remove some includes of //ui/gfx/image/image_skia.h

https: //chromium-review.googlesource.com/c/chromium/src/+/6986762

* fixup! fix: migrate NetworkConditions -> MatchedNetworkConditions https://chromium-review.googlesource.com/c/chromium/src/+/6827307

(cherry picked from commit a8f67f1ac3f8b07354d9457be9addf242ff70000)

* fixup: 6986762: Remove some includes of //ui/gfx/image/image_skia.h

s

* fix: replace deprecated usage of SetPrototype
https://chromium-review.googlesource.com/c/v8/v8/+/6983465

(cherry picked from commit 5435d87b40c15316bc8828fbc197be647b39b7bb)

* chore: restore electron embedder data tag patch

Co-Authored-By: Sam Maddock <sam@samuelmaddock.com>

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Samuel Maddock <smaddock@slack-corp.com>
Co-authored-by: Alice Zhao <alicelovescake@anthropic.com>
Co-authored-by: Sam Maddock <sam@samuelmaddock.com>
2025-10-14 11:25:30 -04:00

1353 lines
42 KiB
C++

// 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 "shell/browser/api/electron_api_base_window.h"
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
#include "base/task/single_thread_task_runner.h"
#include "content/public/common/color_parser.h"
#include "electron/buildflags/buildflags.h"
#include "gin/dictionary.h"
#include "shell/browser/api/electron_api_menu.h"
#include "shell/browser/api/electron_api_view.h"
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/javascript_environment.h"
#include "shell/browser/native_window.h"
#include "shell/common/color_util.h"
#include "shell/common/gin_converters/callback_converter.h"
#include "shell/common/gin_converters/file_path_converter.h"
#include "shell/common/gin_converters/gfx_converter.h"
#include "shell/common/gin_converters/image_converter.h"
#include "shell/common/gin_converters/native_window_converter.h"
#include "shell/common/gin_converters/optional_converter.h"
#include "shell/common/gin_converters/value_converter.h"
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/gin_helper/handle.h"
#include "shell/common/gin_helper/object_template_builder.h"
#include "shell/common/gin_helper/persistent_dictionary.h"
#include "shell/common/node_includes.h"
#include "shell/common/node_util.h"
#include "shell/common/options_switches.h"
#include "ui/gfx/image/image_skia.h"
#if defined(TOOLKIT_VIEWS)
#include "shell/browser/native_window_views.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "shell/browser/ui/views/win_frame_view.h"
#include "shell/browser/ui/win/taskbar_host.h"
#include "ui/base/win/shell.h"
#elif BUILDFLAG(IS_LINUX)
#include "shell/browser/ui/views/opaque_frame_view.h"
#endif
#if BUILDFLAG(IS_WIN)
namespace gin {
template <>
struct Converter<electron::TaskbarHost::ThumbarButton> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
electron::TaskbarHost::ThumbarButton* out) {
gin::Dictionary dict(isolate);
if (!gin::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 gin
#endif
namespace electron::api {
namespace {
#if !BUILDFLAG(IS_MAC)
// Converts binary data to Buffer.
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate,
const base::span<const uint8_t> val) {
auto buffer = electron::Buffer::Copy(isolate, val);
if (buffer.IsEmpty())
return v8::Null(isolate);
else
return buffer.ToLocalChecked();
}
#endif
[[nodiscard]] constexpr std::array<int, 2U> ToArray(const gfx::Size size) {
return {size.width(), size.height()};
}
[[nodiscard]] constexpr std::array<int, 2U> ToArray(const gfx::Point point) {
return {point.x(), point.y()};
}
} // namespace
BaseWindow::BaseWindow(v8::Isolate* isolate,
const gin_helper::Dictionary& options) {
// The parent window.
gin_helper::Handle<BaseWindow> parent;
if (options.Get("parent", &parent) && !parent.IsEmpty())
parent_window_.Reset(isolate, parent.ToV8());
// Offscreen windows are always created frameless.
gin_helper::Dictionary web_preferences;
bool offscreen;
if (options.Get(options::kWebPreferences, &web_preferences) &&
web_preferences.Get(options::kOffscreen, &offscreen) && offscreen) {
const_cast<gin_helper::Dictionary&>(options).Set(options::kFrame, false);
}
// Creates NativeWindow.
window_ = NativeWindow::Create(
options, parent.IsEmpty() ? nullptr : parent->window_.get());
window_->AddObserver(this);
SetContentView(View::Create(isolate));
#if defined(TOOLKIT_VIEWS)
v8::Local<v8::Value> icon;
if (options.Get(options::kIcon, &icon)) {
SetIconImpl(isolate, icon, NativeImage::OnConvertError::kWarn);
}
#endif
}
BaseWindow::BaseWindow(gin_helper::Arguments* args,
const gin_helper::Dictionary& options)
: BaseWindow(args->isolate(), options) {
InitWithArgs(args);
// Init window after everything has been setup.
window()->InitFromOptions(options);
}
BaseWindow::~BaseWindow() {
CloseImmediately();
// Destroy the native window in next tick because the native code might be
// iterating all windows.
base::SingleThreadTaskRunner::GetCurrentDefault()->DeleteSoon(
FROM_HERE, window_.release());
// Remove global reference so the JS object can be garbage collected.
self_ref_.Reset();
}
void BaseWindow::InitWith(v8::Isolate* isolate, v8::Local<v8::Object> wrapper) {
AttachAsUserData(window_.get());
gin_helper::TrackableObject<BaseWindow>::InitWith(isolate, wrapper);
// We can only append this window to parent window's child windows after this
// window's JS wrapper gets initialized.
if (!parent_window_.IsEmpty()) {
gin_helper::Handle<BaseWindow> parent;
gin::ConvertFromV8(isolate, GetParentWindow(), &parent);
DCHECK(!parent.IsEmpty());
parent->child_windows_.Set(isolate, weak_map_id(), wrapper);
}
// Reference this object in case it got garbage collected.
self_ref_.Reset(isolate, wrapper);
}
void BaseWindow::WillCloseWindow(bool* prevent_default) {
if (Emit("close")) {
*prevent_default = true;
}
}
void BaseWindow::OnWindowClosed() {
// Invalidate weak ptrs before the Javascript object is destroyed,
// there might be some delayed emit events which shouldn't be
// triggered after this.
weak_factory_.InvalidateWeakPtrs();
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();
// Destroy the native class when window is closed.
base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, GetDestroyClosure());
}
void BaseWindow::OnWindowQueryEndSession(
const std::vector<std::string>& reasons,
bool* prevent_default) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
gin_helper::internal::Event* event =
gin_helper::internal::Event::New(isolate);
v8::Local<v8::Object> event_object =
event->GetWrapper(isolate).ToLocalChecked();
gin::Dictionary dict(isolate, event_object);
dict.Set("reasons", reasons);
EmitWithoutEvent("query-session-end", event_object);
if (event->GetDefaultPrevented()) {
*prevent_default = true;
}
}
void BaseWindow::OnWindowEndSession(const std::vector<std::string>& reasons) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
gin_helper::internal::Event* event =
gin_helper::internal::Event::New(isolate);
v8::Local<v8::Object> event_object =
event->GetWrapper(isolate).ToLocalChecked();
gin::Dictionary dict(isolate, event_object);
dict.Set("reasons", reasons);
EmitWithoutEvent("session-end", event_object);
}
void BaseWindow::OnWindowBlur() {
EmitEventSoon("blur");
}
void BaseWindow::OnWindowFocus() {
EmitEventSoon("focus");
}
void BaseWindow::OnWindowShow() {
Emit("show");
}
void BaseWindow::OnWindowHide() {
Emit("hide");
}
void BaseWindow::OnWindowMaximize() {
Emit("maximize");
}
void BaseWindow::OnWindowUnmaximize() {
Emit("unmaximize");
}
void BaseWindow::OnWindowMinimize() {
Emit("minimize");
}
void BaseWindow::OnWindowRestore() {
Emit("restore");
}
void BaseWindow::OnWindowWillResize(const gfx::Rect& new_bounds,
const gfx::ResizeEdge edge,
bool* prevent_default) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
auto info = gin::Dictionary::CreateEmpty(isolate);
info.Set("edge", edge);
if (Emit("will-resize", new_bounds, info)) {
*prevent_default = true;
}
}
void BaseWindow::OnWindowResize() {
Emit("resize");
}
void BaseWindow::OnWindowResized() {
Emit("resized");
}
void BaseWindow::OnWindowWillMove(const gfx::Rect& new_bounds,
bool* prevent_default) {
if (Emit("will-move", new_bounds)) {
*prevent_default = true;
}
}
void BaseWindow::OnWindowMove() {
Emit("move");
}
void BaseWindow::OnWindowMoved() {
Emit("moved");
}
void BaseWindow::OnWindowEnterFullScreen() {
Emit("enter-full-screen");
}
void BaseWindow::OnWindowLeaveFullScreen() {
Emit("leave-full-screen");
}
void BaseWindow::OnWindowSwipe(const std::string& direction) {
Emit("swipe", direction);
}
void BaseWindow::OnWindowRotateGesture(float rotation) {
Emit("rotate-gesture", rotation);
}
void BaseWindow::OnWindowSheetBegin() {
Emit("sheet-begin");
}
void BaseWindow::OnWindowSheetEnd() {
Emit("sheet-end");
}
void BaseWindow::OnWindowEnterHtmlFullScreen() {
Emit("enter-html-full-screen");
}
void BaseWindow::OnWindowLeaveHtmlFullScreen() {
Emit("leave-html-full-screen");
}
void BaseWindow::OnWindowAlwaysOnTopChanged() {
Emit("always-on-top-changed", IsAlwaysOnTop());
}
void BaseWindow::OnExecuteAppCommand(const std::string_view command_name) {
Emit("app-command", command_name);
}
void BaseWindow::OnTouchBarItemResult(const std::string& item_id,
const base::Value::Dict& details) {
Emit("-touch-bar-interaction", item_id, details);
}
void BaseWindow::OnNewWindowForTab() {
Emit("new-window-for-tab");
}
void BaseWindow::OnSystemContextMenu(int x, int y, bool* prevent_default) {
if (Emit("system-context-menu", gfx::Point(x, y))) {
*prevent_default = true;
}
}
#if BUILDFLAG(IS_WIN)
void BaseWindow::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
if (IsWindowMessageHooked(message)) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope scope(isolate);
messages_callback_map_[message].Run(
ToBuffer(isolate, base::byte_span_from_ref(w_param)),
ToBuffer(isolate, base::byte_span_from_ref(l_param)));
}
}
#endif
void BaseWindow::SetContentView(gin_helper::Handle<View> view) {
content_view_.Reset(JavascriptEnvironment::GetIsolate(), view.ToV8());
window_->SetContentView(view->view());
}
void BaseWindow::CloseImmediately() {
if (!window_->IsClosed())
window_->CloseImmediately();
}
void BaseWindow::Close() {
window_->Close();
}
void BaseWindow::Focus() {
window_->Focus(true);
}
void BaseWindow::Blur() {
window_->Focus(false);
}
bool BaseWindow::IsFocused() const {
return window_->IsFocused();
}
void BaseWindow::Show() {
window_->Show();
}
void BaseWindow::ShowInactive() {
// This method doesn't make sense for modal window.
if (IsModal())
return;
window_->ShowInactive();
}
void BaseWindow::Hide() {
window_->Hide();
}
bool BaseWindow::IsVisible() const {
return window_->IsVisible();
}
bool BaseWindow::IsEnabled() const {
return window_->IsEnabled();
}
void BaseWindow::SetEnabled(bool enable) {
window_->SetEnabled(enable);
}
void BaseWindow::Maximize() {
window_->Maximize();
}
void BaseWindow::Unmaximize() {
window_->Unmaximize();
}
bool BaseWindow::IsMaximized() const {
return window_->IsMaximized();
}
void BaseWindow::Minimize() {
window_->Minimize();
}
void BaseWindow::Restore() {
window_->Restore();
}
bool BaseWindow::IsMinimized() const {
return window_->IsMinimized();
}
void BaseWindow::SetFullScreen(bool fullscreen) {
window_->SetFullScreen(fullscreen);
}
bool BaseWindow::IsFullscreen() const {
return window_->IsFullscreen();
}
void BaseWindow::SetBounds(const gfx::Rect& bounds,
gin_helper::Arguments* args) {
bool animate = false;
args->GetNext(&animate);
window_->SetBounds(bounds, animate);
}
gfx::Rect BaseWindow::GetBounds() const {
return window_->GetBounds();
}
bool BaseWindow::IsNormal() const {
return window_->IsNormal();
}
gfx::Rect BaseWindow::GetNormalBounds() const {
return window_->GetNormalBounds();
}
void BaseWindow::SetContentBounds(const gfx::Rect& bounds,
gin_helper::Arguments* args) {
bool animate = false;
args->GetNext(&animate);
window_->SetContentBounds(bounds, animate);
}
gfx::Rect BaseWindow::GetContentBounds() const {
return window_->GetContentBounds();
}
void BaseWindow::SetSize(int width, int height, gin_helper::Arguments* args) {
bool animate = false;
gfx::Size size = window_->GetMinimumSize();
size.SetToMax(gfx::Size(width, height));
args->GetNext(&animate);
window_->SetSize(size, animate);
}
std::array<int, 2U> BaseWindow::GetSize() const {
return ToArray(window_->GetSize());
}
void BaseWindow::SetContentSize(int width,
int height,
gin_helper::Arguments* args) {
bool animate = false;
args->GetNext(&animate);
window_->SetContentSize(gfx::Size(width, height), animate);
}
std::array<int, 2U> BaseWindow::GetContentSize() const {
return ToArray(window_->GetContentSize());
}
void BaseWindow::SetMinimumSize(int width, int height) {
window_->SetMinimumSize(gfx::Size(width, height));
}
std::array<int, 2U> BaseWindow::GetMinimumSize() const {
return ToArray(window_->GetMinimumSize());
}
void BaseWindow::SetMaximumSize(int width, int height) {
window_->SetMaximumSize(gfx::Size(width, height));
}
std::array<int, 2U> BaseWindow::GetMaximumSize() const {
return ToArray(window_->GetMaximumSize());
}
void BaseWindow::SetSheetOffset(double offsetY, gin_helper::Arguments* args) {
double offsetX = 0.0;
args->GetNext(&offsetX);
window_->SetSheetOffset(offsetX, offsetY);
}
void BaseWindow::SetResizable(bool resizable) {
window_->SetResizable(resizable);
}
bool BaseWindow::IsResizable() const {
return window_->IsResizable();
}
void BaseWindow::SetMovable(bool movable) {
window_->SetMovable(movable);
}
bool BaseWindow::IsMovable() const {
return window_->IsMovable();
}
void BaseWindow::SetMinimizable(bool minimizable) {
window_->SetMinimizable(minimizable);
}
bool BaseWindow::IsMinimizable() const {
return window_->IsMinimizable();
}
void BaseWindow::SetMaximizable(bool maximizable) {
window_->SetMaximizable(maximizable);
}
bool BaseWindow::IsMaximizable() const {
return window_->IsMaximizable();
}
void BaseWindow::SetFullScreenable(bool fullscreenable) {
window_->SetFullScreenable(fullscreenable);
}
bool BaseWindow::IsFullScreenable() const {
return window_->IsFullScreenable();
}
void BaseWindow::SetClosable(bool closable) {
window_->SetClosable(closable);
}
bool BaseWindow::IsClosable() const {
return window_->IsClosable();
}
void BaseWindow::SetAlwaysOnTop(bool top, gin_helper::Arguments* args) {
std::string level = "floating";
int relative_level = 0;
args->GetNext(&level);
args->GetNext(&relative_level);
ui::ZOrderLevel z_order =
top ? ui::ZOrderLevel::kFloatingWindow : ui::ZOrderLevel::kNormal;
window_->SetAlwaysOnTop(z_order, level, relative_level);
}
bool BaseWindow::IsAlwaysOnTop() const {
return window_->GetZOrderLevel() != ui::ZOrderLevel::kNormal;
}
void BaseWindow::Center() {
window_->Center();
}
void BaseWindow::SetPosition(int x, int y, gin_helper::Arguments* args) {
bool animate = false;
args->GetNext(&animate);
window_->SetPosition(gfx::Point(x, y), animate);
}
std::array<int, 2U> BaseWindow::GetPosition() const {
return ToArray(window_->GetPosition());
}
void BaseWindow::MoveAbove(const std::string& sourceId,
gin_helper::Arguments* args) {
if (!window_->MoveAbove(sourceId))
args->ThrowError("Invalid media source id");
}
void BaseWindow::MoveTop() {
window_->MoveTop();
}
void BaseWindow::SetTitle(const std::string& title) {
window_->SetTitle(title);
}
std::string BaseWindow::GetTitle() const {
return window_->GetTitle();
}
void BaseWindow::SetAccessibleTitle(const std::string& title) {
window_->SetAccessibleTitle(title);
}
std::string BaseWindow::GetAccessibleTitle() const {
return window_->GetAccessibleTitle();
}
void BaseWindow::FlashFrame(bool flash) {
window_->FlashFrame(flash);
}
void BaseWindow::SetSkipTaskbar(bool skip) {
window_->SetSkipTaskbar(skip);
}
void BaseWindow::SetExcludedFromShownWindowsMenu(bool excluded) {
window_->SetExcludedFromShownWindowsMenu(excluded);
}
bool BaseWindow::IsExcludedFromShownWindowsMenu() const {
return window_->IsExcludedFromShownWindowsMenu();
}
void BaseWindow::SetSimpleFullScreen(bool simple_fullscreen) {
window_->SetSimpleFullScreen(simple_fullscreen);
}
bool BaseWindow::IsSimpleFullScreen() const {
return window_->IsSimpleFullScreen();
}
void BaseWindow::SetKiosk(bool kiosk) {
window_->SetKiosk(kiosk);
}
bool BaseWindow::IsKiosk() const {
return window_->IsKiosk();
}
bool BaseWindow::IsTabletMode() const {
return window_->IsTabletMode();
}
void BaseWindow::SetBackgroundColor(const std::string& color_name) {
SkColor color = ParseCSSColor(color_name).value_or(SK_ColorWHITE);
window_->SetBackgroundColor(color);
}
std::string BaseWindow::GetBackgroundColor() const {
return ToRGBHex(window_->GetBackgroundColor());
}
void BaseWindow::InvalidateShadow() {
window_->InvalidateShadow();
}
void BaseWindow::SetHasShadow(bool has_shadow) {
window_->SetHasShadow(has_shadow);
}
bool BaseWindow::HasShadow() const {
return window_->HasShadow();
}
void BaseWindow::SetOpacity(const double opacity) {
window_->SetOpacity(opacity);
}
double BaseWindow::GetOpacity() const {
return window_->GetOpacity();
}
void BaseWindow::SetShape(const std::vector<gfx::Rect>& rects) {
window_->SetShape(rects);
}
void BaseWindow::SetRepresentedFilename(const std::string& filename) {
window_->SetRepresentedFilename(filename);
}
std::string BaseWindow::GetRepresentedFilename() const {
return window_->GetRepresentedFilename();
}
void BaseWindow::SetDocumentEdited(bool edited) {
window_->SetDocumentEdited(edited);
}
bool BaseWindow::IsDocumentEdited() const {
return window_->IsDocumentEdited();
}
void BaseWindow::SetIgnoreMouseEvents(bool ignore,
gin_helper::Arguments* args) {
gin_helper::Dictionary options;
bool forward = false;
args->GetNext(&options) && options.Get("forward", &forward);
return window_->SetIgnoreMouseEvents(ignore, forward);
}
void BaseWindow::SetContentProtection(bool enable) {
return window_->SetContentProtection(enable);
}
bool BaseWindow::IsContentProtected() const {
return window_->IsContentProtected();
}
void BaseWindow::SetFocusable(bool focusable) {
return window_->SetFocusable(focusable);
}
bool BaseWindow::IsFocusable() const {
return window_->IsFocusable();
}
void BaseWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
auto context = isolate->GetCurrentContext();
gin_helper::Handle<Menu> menu;
v8::Local<v8::Object> object;
if (value->IsObject() && value->ToObject(context).ToLocal(&object) &&
gin::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) {
// We only want to update the menu if the menu has a non-zero item count,
// or we risk crashes.
if (menu->model()->GetItemCount() == 0) {
RemoveMenu();
} else {
window_->SetMenu(menu->model());
}
menu_.Reset(isolate, menu.ToV8());
} else if (value->IsNull()) {
RemoveMenu();
} else {
isolate->ThrowException(
v8::Exception::TypeError(gin::StringToV8(isolate, "Invalid Menu")));
}
}
void BaseWindow::RemoveMenu() {
menu_.Reset();
window_->SetMenu(nullptr);
}
void BaseWindow::SetParentWindow(v8::Local<v8::Value> value,
gin_helper::Arguments* args) {
if (IsModal()) {
args->ThrowError("Can not be called for modal window");
return;
}
gin_helper::Handle<BaseWindow> parent;
if (value->IsNull() || value->IsUndefined()) {
RemoveFromParentChildWindows();
parent_window_.Reset();
window_->SetParentWindow(nullptr);
} else if (gin::ConvertFromV8(isolate(), value, &parent)) {
RemoveFromParentChildWindows();
parent_window_.Reset(isolate(), value);
window_->SetParentWindow(parent->window_.get());
parent->child_windows_.Set(isolate(), weak_map_id(), GetWrapper());
} else {
args->ThrowError("Must pass BaseWindow instance or null");
}
}
std::string BaseWindow::GetMediaSourceId() const {
return window_->GetDesktopMediaID().ToString();
}
#if !BUILDFLAG(IS_MAC)
v8::Local<v8::Value> BaseWindow::GetNativeWindowHandle() {
// TODO(MarshallOfSound): Replace once
// https://chromium-review.googlesource.com/c/chromium/src/+/1253094/ has
// landed
NativeWindowHandle handle = window_->GetNativeWindowHandle();
return ToBuffer(isolate(), base::byte_span_from_ref(handle));
}
#endif
void BaseWindow::SetProgressBar(double progress, gin_helper::Arguments* args) {
gin_helper::Dictionary options;
std::string mode;
args->GetNext(&options) && options.Get("mode", &mode);
NativeWindow::ProgressState state = NativeWindow::ProgressState::kNormal;
if (mode == "error")
state = NativeWindow::ProgressState::kError;
else if (mode == "paused")
state = NativeWindow::ProgressState::kPaused;
else if (mode == "indeterminate")
state = NativeWindow::ProgressState::kIndeterminate;
else if (mode == "none")
state = NativeWindow::ProgressState::kNone;
window_->SetProgressBar(progress, state);
}
void BaseWindow::SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) {
window_->SetOverlayIcon(overlay, description);
}
void BaseWindow::SetVisibleOnAllWorkspaces(bool visible,
gin_helper::Arguments* args) {
gin_helper::Dictionary options;
bool visibleOnFullScreen = false;
bool skipTransformProcessType = false;
if (args->GetNext(&options)) {
options.Get("visibleOnFullScreen", &visibleOnFullScreen);
options.Get("skipTransformProcessType", &skipTransformProcessType);
}
return window_->SetVisibleOnAllWorkspaces(visible, visibleOnFullScreen,
skipTransformProcessType);
}
bool BaseWindow::IsVisibleOnAllWorkspaces() const {
return window_->IsVisibleOnAllWorkspaces();
}
void BaseWindow::SetAutoHideCursor(bool auto_hide) {
window_->SetAutoHideCursor(auto_hide);
}
void BaseWindow::SetVibrancy(v8::Isolate* isolate,
v8::Local<v8::Value> value,
gin_helper::Arguments* args) {
std::string type = gin::V8ToString(isolate, value);
gin_helper::Dictionary options;
int animation_duration_ms = 0;
if (args->GetNext(&options)) {
options.Get("animationDuration", &animation_duration_ms);
}
window_->SetVibrancy(type, animation_duration_ms);
}
void BaseWindow::SetBackgroundMaterial(const std::string& material) {
window_->SetBackgroundMaterial(material);
}
#if BUILDFLAG(IS_MAC)
std::string BaseWindow::GetAlwaysOnTopLevel() const {
return window_->GetAlwaysOnTopLevel();
}
void BaseWindow::SetWindowButtonVisibility(bool visible) {
window_->SetWindowButtonVisibility(visible);
}
bool BaseWindow::GetWindowButtonVisibility() const {
return window_->GetWindowButtonVisibility();
}
void BaseWindow::SetWindowButtonPosition(std::optional<gfx::Point> position) {
window_->SetWindowButtonPosition(std::move(position));
}
std::optional<gfx::Point> BaseWindow::GetWindowButtonPosition() const {
return window_->GetWindowButtonPosition();
}
#endif
#if BUILDFLAG(IS_MAC)
bool BaseWindow::IsHiddenInMissionControl() {
return window_->IsHiddenInMissionControl();
}
void BaseWindow::SetHiddenInMissionControl(bool hidden) {
window_->SetHiddenInMissionControl(hidden);
}
#endif
void BaseWindow::SetTouchBar(
std::vector<gin_helper::PersistentDictionary> items) {
window_->SetTouchBar(std::move(items));
}
void BaseWindow::RefreshTouchBarItem(const std::string& item_id) {
window_->RefreshTouchBarItem(item_id);
}
void BaseWindow::SetEscapeTouchBarItem(gin_helper::PersistentDictionary item) {
window_->SetEscapeTouchBarItem(std::move(item));
}
void BaseWindow::SelectPreviousTab() {
window_->SelectPreviousTab();
}
void BaseWindow::SelectNextTab() {
window_->SelectNextTab();
}
void BaseWindow::ShowAllTabs() {
window_->ShowAllTabs();
}
void BaseWindow::MergeAllWindows() {
window_->MergeAllWindows();
}
void BaseWindow::MoveTabToNewWindow() {
window_->MoveTabToNewWindow();
}
void BaseWindow::ToggleTabBar() {
window_->ToggleTabBar();
}
void BaseWindow::AddTabbedWindow(NativeWindow* window,
gin_helper::Arguments* args) {
if (!window_->AddTabbedWindow(window))
args->ThrowError("AddTabbedWindow cannot be called by a window on itself.");
}
v8::Local<v8::Value> BaseWindow::GetTabbingIdentifier() {
auto tabbing_id = window_->GetTabbingIdentifier();
if (!tabbing_id.has_value())
return v8::Undefined(isolate());
return gin::ConvertToV8(isolate(), tabbing_id.value());
}
void BaseWindow::SetAutoHideMenuBar(bool auto_hide) {
window_->SetAutoHideMenuBar(auto_hide);
}
bool BaseWindow::IsMenuBarAutoHide() const {
return window_->IsMenuBarAutoHide();
}
void BaseWindow::SetMenuBarVisibility(bool visible) {
window_->SetMenuBarVisibility(visible);
}
bool BaseWindow::IsMenuBarVisible() const {
return window_->IsMenuBarVisible();
}
void BaseWindow::SetAspectRatio(double aspect_ratio,
gin_helper::Arguments* args) {
gfx::Size extra_size;
args->GetNext(&extra_size);
window_->SetAspectRatio(aspect_ratio, extra_size);
}
void BaseWindow::PreviewFile(const std::string& path,
gin_helper::Arguments* args) {
std::string display_name;
if (!args->GetNext(&display_name))
display_name = path;
window_->PreviewFile(path, display_name);
}
void BaseWindow::CloseFilePreview() {
window_->CloseFilePreview();
}
void BaseWindow::SetGTKDarkThemeEnabled(bool use_dark_theme) {
window_->SetGTKDarkThemeEnabled(use_dark_theme);
}
v8::Local<v8::Value> BaseWindow::GetContentView() const {
if (content_view_.IsEmpty())
return v8::Null(isolate());
else
return v8::Local<v8::Value>::New(isolate(), content_view_);
}
v8::Local<v8::Value> BaseWindow::GetParentWindow() const {
if (parent_window_.IsEmpty())
return v8::Null(isolate());
else
return v8::Local<v8::Value>::New(isolate(), parent_window_);
}
std::vector<v8::Local<v8::Object>> BaseWindow::GetChildWindows() const {
return child_windows_.Values(isolate());
}
bool BaseWindow::IsModal() const {
return window_->is_modal();
}
bool BaseWindow::SetThumbarButtons(gin_helper::Arguments* args) {
#if BUILDFLAG(IS_WIN)
std::vector<TaskbarHost::ThumbarButton> buttons;
if (!args->GetNext(&buttons)) {
args->ThrowError();
return false;
}
auto* window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbarButtons(
window_->GetAcceleratedWidget(), buttons);
#else
return false;
#endif
}
#if defined(TOOLKIT_VIEWS)
void BaseWindow::SetIcon(v8::Isolate* isolate, v8::Local<v8::Value> icon) {
SetIconImpl(isolate, icon, NativeImage::OnConvertError::kThrow);
}
void BaseWindow::SetIconImpl(v8::Isolate* isolate,
v8::Local<v8::Value> icon,
NativeImage::OnConvertError on_error) {
NativeImage* native_image = nullptr;
if (!NativeImage::TryConvertNativeImage(isolate, icon, &native_image,
on_error))
return;
#if BUILDFLAG(IS_WIN)
static_cast<NativeWindowViews*>(window_.get())
->SetIcon(native_image->GetHICON(GetSystemMetrics(SM_CXSMICON)),
native_image->GetHICON(GetSystemMetrics(SM_CXICON)));
#elif BUILDFLAG(IS_LINUX)
static_cast<NativeWindowViews*>(window_.get())
->SetIcon(native_image->image().AsImageSkia());
#endif
}
#endif
#if BUILDFLAG(IS_WIN)
bool BaseWindow::HookWindowMessage(UINT message,
const MessageCallback& callback) {
messages_callback_map_[message] = callback;
return true;
}
void BaseWindow::UnhookWindowMessage(UINT message) {
messages_callback_map_.erase(message);
}
bool BaseWindow::IsWindowMessageHooked(UINT message) {
return messages_callback_map_.contains(message);
}
void BaseWindow::UnhookAllWindowMessages() {
messages_callback_map_.clear();
}
bool BaseWindow::SetThumbnailClip(const gfx::Rect& region) {
auto* window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbnailClip(
window_->GetAcceleratedWidget(), region);
}
bool BaseWindow::SetThumbnailToolTip(const std::string& tooltip) {
auto* window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbnailToolTip(
window_->GetAcceleratedWidget(), tooltip);
}
void BaseWindow::SetAppDetails(const gin_helper::Dictionary& options) {
std::wstring app_id;
base::FilePath app_icon_path;
int app_icon_index = 0;
std::wstring relaunch_command;
std::wstring 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());
}
bool BaseWindow::IsSnapped() const {
return window_->IsSnapped();
}
void BaseWindow::SetAccentColor(gin_helper::Arguments* args) {
bool accent_color = false;
std::string accent_color_string;
if (args->GetNext(&accent_color_string)) {
std::optional<SkColor> maybe_color = ParseCSSColor(accent_color_string);
if (maybe_color.has_value()) {
window_->SetAccentColor(maybe_color.value());
window_->UpdateWindowAccentColor(window_->IsActive());
}
} else if (args->GetNext(&accent_color)) {
window_->SetAccentColor(accent_color);
window_->UpdateWindowAccentColor(window_->IsActive());
} else {
args->ThrowError(
"Invalid accent color value - must be a string or boolean");
}
}
v8::Local<v8::Value> BaseWindow::GetAccentColor() const {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
auto accent_color = window_->GetAccentColor();
if (std::holds_alternative<bool>(accent_color))
return v8::Boolean::New(isolate, std::get<bool>(accent_color));
return gin::StringToV8(isolate, std::get<std::string>(accent_color));
}
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
void BaseWindow::SetTitleBarOverlay(const gin_helper::Dictionary& options,
gin_helper::Arguments* args) {
static_cast<NativeWindowViews*>(window_.get())
->SetTitleBarOverlay(options, args);
}
#endif
void BaseWindow::RemoveFromParentChildWindows() {
if (parent_window_.IsEmpty())
return;
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
gin_helper::Handle<BaseWindow> parent;
if (!gin::ConvertFromV8(isolate, GetParentWindow(), &parent) ||
parent.IsEmpty()) {
return;
}
parent->child_windows_.Remove(weak_map_id());
}
// static
gin_helper::WrappableBase* BaseWindow::New(gin_helper::Arguments* args) {
auto options = gin_helper::Dictionary::CreateEmpty(args->isolate());
args->GetNext(&options);
return new BaseWindow(args, options);
}
// static
void BaseWindow::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(gin::StringToV8(isolate, "BaseWindow"));
gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("setContentView", &BaseWindow::SetContentView)
.SetMethod("close", &BaseWindow::Close)
.SetMethod("focus", &BaseWindow::Focus)
.SetMethod("blur", &BaseWindow::Blur)
.SetMethod("isFocused", &BaseWindow::IsFocused)
.SetMethod("show", &BaseWindow::Show)
.SetMethod("showInactive", &BaseWindow::ShowInactive)
.SetMethod("hide", &BaseWindow::Hide)
.SetMethod("isVisible", &BaseWindow::IsVisible)
.SetMethod("isEnabled", &BaseWindow::IsEnabled)
.SetMethod("setEnabled", &BaseWindow::SetEnabled)
.SetMethod("maximize", &BaseWindow::Maximize)
.SetMethod("unmaximize", &BaseWindow::Unmaximize)
.SetMethod("isMaximized", &BaseWindow::IsMaximized)
.SetMethod("minimize", &BaseWindow::Minimize)
.SetMethod("restore", &BaseWindow::Restore)
.SetMethod("isMinimized", &BaseWindow::IsMinimized)
.SetMethod("setFullScreen", &BaseWindow::SetFullScreen)
.SetMethod("isFullScreen", &BaseWindow::IsFullscreen)
.SetMethod("setBounds", &BaseWindow::SetBounds)
.SetMethod("getBounds", &BaseWindow::GetBounds)
.SetMethod("isNormal", &BaseWindow::IsNormal)
.SetMethod("getNormalBounds", &BaseWindow::GetNormalBounds)
.SetMethod("setSize", &BaseWindow::SetSize)
.SetMethod("getSize", &BaseWindow::GetSize)
.SetMethod("setContentBounds", &BaseWindow::SetContentBounds)
.SetMethod("getContentBounds", &BaseWindow::GetContentBounds)
.SetMethod("setContentSize", &BaseWindow::SetContentSize)
.SetMethod("getContentSize", &BaseWindow::GetContentSize)
.SetMethod("setMinimumSize", &BaseWindow::SetMinimumSize)
.SetMethod("getMinimumSize", &BaseWindow::GetMinimumSize)
.SetMethod("setMaximumSize", &BaseWindow::SetMaximumSize)
.SetMethod("getMaximumSize", &BaseWindow::GetMaximumSize)
.SetMethod("setSheetOffset", &BaseWindow::SetSheetOffset)
.SetMethod("moveAbove", &BaseWindow::MoveAbove)
.SetMethod("moveTop", &BaseWindow::MoveTop)
.SetMethod("setResizable", &BaseWindow::SetResizable)
.SetMethod("isResizable", &BaseWindow::IsResizable)
.SetMethod("setMovable", &BaseWindow::SetMovable)
.SetMethod("isMovable", &BaseWindow::IsMovable)
.SetMethod("setMinimizable", &BaseWindow::SetMinimizable)
.SetMethod("isMinimizable", &BaseWindow::IsMinimizable)
.SetMethod("setMaximizable", &BaseWindow::SetMaximizable)
.SetMethod("isMaximizable", &BaseWindow::IsMaximizable)
.SetMethod("setFullScreenable", &BaseWindow::SetFullScreenable)
.SetMethod("isFullScreenable", &BaseWindow::IsFullScreenable)
.SetMethod("setClosable", &BaseWindow::SetClosable)
.SetMethod("isClosable", &BaseWindow::IsClosable)
.SetMethod("setAlwaysOnTop", &BaseWindow::SetAlwaysOnTop)
.SetMethod("isAlwaysOnTop", &BaseWindow::IsAlwaysOnTop)
.SetMethod("center", &BaseWindow::Center)
.SetMethod("setPosition", &BaseWindow::SetPosition)
.SetMethod("getPosition", &BaseWindow::GetPosition)
.SetMethod("setTitle", &BaseWindow::SetTitle)
.SetMethod("getTitle", &BaseWindow::GetTitle)
.SetProperty("accessibleTitle", &BaseWindow::GetAccessibleTitle,
&BaseWindow::SetAccessibleTitle)
.SetMethod("flashFrame", &BaseWindow::FlashFrame)
.SetMethod("setSkipTaskbar", &BaseWindow::SetSkipTaskbar)
.SetMethod("setSimpleFullScreen", &BaseWindow::SetSimpleFullScreen)
.SetMethod("isSimpleFullScreen", &BaseWindow::IsSimpleFullScreen)
.SetMethod("setKiosk", &BaseWindow::SetKiosk)
.SetMethod("isKiosk", &BaseWindow::IsKiosk)
.SetMethod("isTabletMode", &BaseWindow::IsTabletMode)
.SetMethod("setBackgroundColor", &BaseWindow::SetBackgroundColor)
.SetMethod("getBackgroundColor", &BaseWindow::GetBackgroundColor)
.SetMethod("setHasShadow", &BaseWindow::SetHasShadow)
.SetMethod("hasShadow", &BaseWindow::HasShadow)
.SetMethod("setOpacity", &BaseWindow::SetOpacity)
.SetMethod("getOpacity", &BaseWindow::GetOpacity)
.SetMethod("setShape", &BaseWindow::SetShape)
.SetMethod("setRepresentedFilename", &BaseWindow::SetRepresentedFilename)
.SetMethod("getRepresentedFilename", &BaseWindow::GetRepresentedFilename)
.SetMethod("setDocumentEdited", &BaseWindow::SetDocumentEdited)
.SetMethod("isDocumentEdited", &BaseWindow::IsDocumentEdited)
.SetMethod("setIgnoreMouseEvents", &BaseWindow::SetIgnoreMouseEvents)
.SetMethod("setContentProtection", &BaseWindow::SetContentProtection)
.SetMethod("isContentProtected", &BaseWindow::IsContentProtected)
.SetMethod("setFocusable", &BaseWindow::SetFocusable)
.SetMethod("isFocusable", &BaseWindow::IsFocusable)
.SetMethod("setMenu", &BaseWindow::SetMenu)
.SetMethod("removeMenu", &BaseWindow::RemoveMenu)
.SetMethod("setParentWindow", &BaseWindow::SetParentWindow)
.SetMethod("getMediaSourceId", &BaseWindow::GetMediaSourceId)
.SetMethod("getNativeWindowHandle", &BaseWindow::GetNativeWindowHandle)
.SetMethod("setProgressBar", &BaseWindow::SetProgressBar)
.SetMethod("setOverlayIcon", &BaseWindow::SetOverlayIcon)
.SetMethod("setVisibleOnAllWorkspaces",
&BaseWindow::SetVisibleOnAllWorkspaces)
.SetMethod("isVisibleOnAllWorkspaces",
&BaseWindow::IsVisibleOnAllWorkspaces)
#if BUILDFLAG(IS_MAC)
.SetMethod("invalidateShadow", &BaseWindow::InvalidateShadow)
.SetMethod("_getAlwaysOnTopLevel", &BaseWindow::GetAlwaysOnTopLevel)
.SetMethod("setAutoHideCursor", &BaseWindow::SetAutoHideCursor)
#endif
.SetMethod("setVibrancy", &BaseWindow::SetVibrancy)
.SetMethod("setBackgroundMaterial", &BaseWindow::SetBackgroundMaterial)
#if BUILDFLAG(IS_MAC)
.SetMethod("isHiddenInMissionControl",
&BaseWindow::IsHiddenInMissionControl)
.SetMethod("setHiddenInMissionControl",
&BaseWindow::SetHiddenInMissionControl)
#endif
.SetMethod("_setTouchBarItems", &BaseWindow::SetTouchBar)
.SetMethod("_refreshTouchBarItem", &BaseWindow::RefreshTouchBarItem)
.SetMethod("_setEscapeTouchBarItem", &BaseWindow::SetEscapeTouchBarItem)
#if BUILDFLAG(IS_MAC)
.SetMethod("selectPreviousTab", &BaseWindow::SelectPreviousTab)
.SetMethod("selectNextTab", &BaseWindow::SelectNextTab)
.SetMethod("showAllTabs", &BaseWindow::ShowAllTabs)
.SetMethod("mergeAllWindows", &BaseWindow::MergeAllWindows)
.SetMethod("moveTabToNewWindow", &BaseWindow::MoveTabToNewWindow)
.SetMethod("toggleTabBar", &BaseWindow::ToggleTabBar)
.SetMethod("addTabbedWindow", &BaseWindow::AddTabbedWindow)
.SetProperty("tabbingIdentifier", &BaseWindow::GetTabbingIdentifier)
.SetMethod("setWindowButtonVisibility",
&BaseWindow::SetWindowButtonVisibility)
.SetMethod("_getWindowButtonVisibility",
&BaseWindow::GetWindowButtonVisibility)
.SetMethod("setWindowButtonPosition",
&BaseWindow::SetWindowButtonPosition)
.SetMethod("getWindowButtonPosition",
&BaseWindow::GetWindowButtonPosition)
.SetProperty("excludedFromShownWindowsMenu",
&BaseWindow::IsExcludedFromShownWindowsMenu,
&BaseWindow::SetExcludedFromShownWindowsMenu)
#endif
.SetMethod("setAutoHideMenuBar", &BaseWindow::SetAutoHideMenuBar)
.SetMethod("isMenuBarAutoHide", &BaseWindow::IsMenuBarAutoHide)
.SetMethod("setMenuBarVisibility", &BaseWindow::SetMenuBarVisibility)
.SetMethod("isMenuBarVisible", &BaseWindow::IsMenuBarVisible)
.SetMethod("setAspectRatio", &BaseWindow::SetAspectRatio)
.SetMethod("previewFile", &BaseWindow::PreviewFile)
.SetMethod("closeFilePreview", &BaseWindow::CloseFilePreview)
.SetMethod("getContentView", &BaseWindow::GetContentView)
.SetProperty("contentView", &BaseWindow::GetContentView,
&BaseWindow::SetContentView)
.SetMethod("getParentWindow", &BaseWindow::GetParentWindow)
.SetMethod("getChildWindows", &BaseWindow::GetChildWindows)
.SetMethod("isModal", &BaseWindow::IsModal)
.SetMethod("setThumbarButtons", &BaseWindow::SetThumbarButtons)
#if defined(TOOLKIT_VIEWS)
.SetMethod("setIcon", &BaseWindow::SetIcon)
#endif
#if BUILDFLAG(IS_WIN)
.SetMethod("isSnapped", &BaseWindow::IsSnapped)
.SetProperty("snapped", &BaseWindow::IsSnapped)
.SetMethod("setAccentColor", &BaseWindow::SetAccentColor)
.SetMethod("getAccentColor", &BaseWindow::GetAccentColor)
.SetMethod("hookWindowMessage", &BaseWindow::HookWindowMessage)
.SetMethod("isWindowMessageHooked", &BaseWindow::IsWindowMessageHooked)
.SetMethod("unhookWindowMessage", &BaseWindow::UnhookWindowMessage)
.SetMethod("unhookAllWindowMessages",
&BaseWindow::UnhookAllWindowMessages)
.SetMethod("setThumbnailClip", &BaseWindow::SetThumbnailClip)
.SetMethod("setThumbnailToolTip", &BaseWindow::SetThumbnailToolTip)
.SetMethod("setAppDetails", &BaseWindow::SetAppDetails)
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
.SetMethod("setTitleBarOverlay", &BaseWindow::SetTitleBarOverlay)
#endif
.SetProperty("id", &BaseWindow::GetID);
}
} // namespace electron::api
namespace {
using electron::api::BaseWindow;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* const isolate = electron::JavascriptEnvironment::GetIsolate();
BaseWindow::SetConstructor(isolate, base::BindRepeating(&BaseWindow::New));
gin_helper::Dictionary constructor(isolate,
BaseWindow::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
constructor.SetMethod("fromId", &BaseWindow::FromWeakMapID);
constructor.SetMethod("getAllWindows", &BaseWindow::GetAll);
gin_helper::Dictionary dict(isolate, exports);
dict.Set("BaseWindow", constructor);
}
} // namespace
NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_base_window, Initialize)