mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
10 Commits
v33.0.0-be
...
v33.0.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad8f2f8d5d | ||
|
|
53cc8aef9b | ||
|
|
0ffafbc295 | ||
|
|
134176a1d1 | ||
|
|
d2bd4cf91c | ||
|
|
1af736bc15 | ||
|
|
f609d77e29 | ||
|
|
ae6d5c4661 | ||
|
|
cdcfe49592 | ||
|
|
d35b848f95 |
1
BUILD.gn
1
BUILD.gn
@@ -75,6 +75,7 @@ if (is_linux) {
|
||||
"notify_notification_set_timeout",
|
||||
"notify_notification_set_urgency",
|
||||
"notify_notification_set_hint_string",
|
||||
"notify_notification_set_hint",
|
||||
"notify_notification_show",
|
||||
"notify_notification_close",
|
||||
]
|
||||
|
||||
@@ -2892,14 +2892,16 @@ bool WebContents::IsCurrentlyAudible() {
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
void WebContents::OnGetDeviceNameToUse(
|
||||
base::Value::Dict print_settings,
|
||||
printing::CompletionCallback print_callback,
|
||||
// <error, device_name>
|
||||
std::pair<std::string, std::u16string> info) {
|
||||
namespace {
|
||||
|
||||
void OnGetDeviceNameToUse(base::WeakPtr<content::WebContents> web_contents,
|
||||
base::Value::Dict print_settings,
|
||||
printing::CompletionCallback print_callback,
|
||||
// <error, device_name>
|
||||
std::pair<std::string, std::u16string> info) {
|
||||
// The content::WebContents might be already deleted at this point, and the
|
||||
// PrintViewManagerElectron class does not do null check.
|
||||
if (!web_contents()) {
|
||||
if (!web_contents) {
|
||||
if (print_callback)
|
||||
std::move(print_callback).Run(false, "failed");
|
||||
return;
|
||||
@@ -2921,15 +2923,40 @@ void WebContents::OnGetDeviceNameToUse(
|
||||
}
|
||||
|
||||
auto* print_view_manager =
|
||||
PrintViewManagerElectron::FromWebContents(web_contents());
|
||||
PrintViewManagerElectron::FromWebContents(web_contents.get());
|
||||
if (!print_view_manager)
|
||||
return;
|
||||
|
||||
content::RenderFrameHost* rfh = GetRenderFrameHostToUse(web_contents());
|
||||
content::RenderFrameHost* rfh = GetRenderFrameHostToUse(web_contents.get());
|
||||
print_view_manager->PrintNow(rfh, std::move(print_settings),
|
||||
std::move(print_callback));
|
||||
}
|
||||
|
||||
void OnPDFCreated(gin_helper::Promise<v8::Local<v8::Value>> promise,
|
||||
print_to_pdf::PdfPrintResult print_result,
|
||||
scoped_refptr<base::RefCountedMemory> data) {
|
||||
if (print_result != print_to_pdf::PdfPrintResult::kPrintSuccess) {
|
||||
promise.RejectWithErrorMessage(
|
||||
"Failed to generate PDF: " +
|
||||
print_to_pdf::PdfPrintResultToString(print_result));
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Isolate* isolate = promise.isolate();
|
||||
gin_helper::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Context::Scope context_scope(
|
||||
v8::Local<v8::Context>::New(isolate, promise.GetContext()));
|
||||
|
||||
v8::Local<v8::Value> buffer =
|
||||
node::Buffer::Copy(isolate, reinterpret_cast<const char*>(data->front()),
|
||||
data->size())
|
||||
.ToLocalChecked();
|
||||
|
||||
promise.Resolve(buffer);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void WebContents::Print(gin::Arguments* args) {
|
||||
auto options = gin_helper::Dictionary::CreateEmpty(args->isolate());
|
||||
base::Value::Dict settings;
|
||||
@@ -3089,9 +3116,8 @@ void WebContents::Print(gin::Arguments* args) {
|
||||
|
||||
print_task_runner_->PostTaskAndReplyWithResult(
|
||||
FROM_HERE, base::BindOnce(&GetDeviceNameToUse, device_name),
|
||||
base::BindOnce(&WebContents::OnGetDeviceNameToUse,
|
||||
weak_factory_.GetWeakPtr(), std::move(settings),
|
||||
std::move(callback)));
|
||||
base::BindOnce(&OnGetDeviceNameToUse, web_contents()->GetWeakPtr(),
|
||||
std::move(settings), std::move(callback)));
|
||||
}
|
||||
|
||||
// Partially duplicated and modified from
|
||||
@@ -3149,36 +3175,10 @@ v8::Local<v8::Promise> WebContents::PrintToPDF(const base::Value& settings) {
|
||||
params->params->document_cookie = unique_id.value_or(0);
|
||||
|
||||
manager->PrintToPdf(rfh, page_ranges, std::move(params),
|
||||
base::BindOnce(&WebContents::OnPDFCreated, GetWeakPtr(),
|
||||
std::move(promise)));
|
||||
base::BindOnce(&OnPDFCreated, std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void WebContents::OnPDFCreated(
|
||||
gin_helper::Promise<v8::Local<v8::Value>> promise,
|
||||
print_to_pdf::PdfPrintResult print_result,
|
||||
scoped_refptr<base::RefCountedMemory> data) {
|
||||
if (print_result != print_to_pdf::PdfPrintResult::kPrintSuccess) {
|
||||
promise.RejectWithErrorMessage(
|
||||
"Failed to generate PDF: " +
|
||||
print_to_pdf::PdfPrintResultToString(print_result));
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Isolate* isolate = promise.isolate();
|
||||
gin_helper::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Context::Scope context_scope(
|
||||
v8::Local<v8::Context>::New(isolate, promise.GetContext()));
|
||||
|
||||
v8::Local<v8::Value> buffer =
|
||||
node::Buffer::Copy(isolate, reinterpret_cast<const char*>(data->front()),
|
||||
data->size())
|
||||
.ToLocalChecked();
|
||||
|
||||
promise.Resolve(buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
void WebContents::AddWorkSpace(gin::Arguments* args,
|
||||
@@ -3320,6 +3320,12 @@ void WebContents::Focus() {
|
||||
if (owner_window())
|
||||
owner_window()->Focus(true);
|
||||
#endif
|
||||
|
||||
// WebView uses WebContentsViewChildFrame, which doesn't have a Focus impl
|
||||
// and triggers a fatal NOTREACHED.
|
||||
if (is_guest())
|
||||
return;
|
||||
|
||||
web_contents()->Focus();
|
||||
}
|
||||
|
||||
@@ -3748,7 +3754,8 @@ void WebContents::SetBackgroundColor(std::optional<SkColor> maybe_color) {
|
||||
|
||||
content::RenderWidgetHostView* rwhv = rfh->GetView();
|
||||
if (rwhv) {
|
||||
// RenderWidgetHostView doesn't allow setting an alpha that's not 0 or 255.
|
||||
// RenderWidgetHostView doesn't allow setting an alpha that's not 0 or
|
||||
// 255.
|
||||
rwhv->SetBackgroundColor(is_opaque ? color : SK_ColorTRANSPARENT);
|
||||
static_cast<content::RenderWidgetHostViewBase*>(rwhv)
|
||||
->SetContentBackgroundColor(color);
|
||||
|
||||
@@ -45,10 +45,6 @@
|
||||
#include "shell/common/gin_helper/pinnable.h"
|
||||
#include "ui/base/models/image_model.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
#include "shell/browser/printing/print_view_manager_electron.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "extensions/common/mojom/view_type.mojom-forward.h"
|
||||
|
||||
@@ -246,16 +242,9 @@ class WebContents final : public ExclusiveAccessContext,
|
||||
void HandleNewRenderFrame(content::RenderFrameHost* render_frame_host);
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
void OnGetDeviceNameToUse(base::Value::Dict print_settings,
|
||||
printing::CompletionCallback print_callback,
|
||||
// <error, device_name>
|
||||
std::pair<std::string, std::u16string> info);
|
||||
void Print(gin::Arguments* args);
|
||||
// Print current page as PDF.
|
||||
v8::Local<v8::Promise> PrintToPDF(const base::Value& settings);
|
||||
void OnPDFCreated(gin_helper::Promise<v8::Local<v8::Value>> promise,
|
||||
print_to_pdf::PdfPrintResult print_result,
|
||||
scoped_refptr<base::RefCountedMemory> data);
|
||||
#endif
|
||||
|
||||
void SetNextChildWebPreferences(const gin_helper::Dictionary);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "device/bluetooth/bluetooth_device.h"
|
||||
|
||||
@@ -352,8 +352,11 @@ void NativeWindowMac::Close() {
|
||||
// [window_ performClose:nil], the window won't close properly
|
||||
// even after the user has ended the sheet.
|
||||
// Ensure it's closed before calling [window_ performClose:nil].
|
||||
if ([window_ attachedSheet])
|
||||
// If multiple sheets are open, they must all be closed.
|
||||
while ([window_ attachedSheet]) {
|
||||
[window_ endSheet:[window_ attachedSheet]];
|
||||
}
|
||||
DCHECK_EQ([[window_ sheets] count], 0UL);
|
||||
|
||||
// window_ could be nil after performClose.
|
||||
bool should_notify = is_modal() && parent() && IsVisible();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "base/files/file_enumerator.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/process/process_handle.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "shell/browser/notifications/notification_delegate.h"
|
||||
#include "shell/browser/ui/gtk_util.h"
|
||||
@@ -145,6 +146,10 @@ void LibnotifyNotification::Show(const NotificationOptions& options) {
|
||||
notification_, "desktop-entry", desktop_id.c_str());
|
||||
}
|
||||
|
||||
libnotify_loader_.notify_notification_set_hint(
|
||||
notification_, "sender-pid",
|
||||
g_variant_new_int64(base::GetCurrentProcId()));
|
||||
|
||||
GError* error = nullptr;
|
||||
libnotify_loader_.notify_notification_show(notification_, &error);
|
||||
if (error) {
|
||||
|
||||
@@ -87,17 +87,17 @@ class OffScreenRenderWidgetHostView
|
||||
void InitAsChild(gfx::NativeView) override;
|
||||
void SetSize(const gfx::Size&) override;
|
||||
void SetBounds(const gfx::Rect&) override;
|
||||
gfx::NativeView GetNativeView(void) override;
|
||||
gfx::NativeViewAccessible GetNativeViewAccessible(void) override;
|
||||
gfx::NativeView GetNativeView() override;
|
||||
gfx::NativeViewAccessible GetNativeViewAccessible() override;
|
||||
ui::TextInputClient* GetTextInputClient() override;
|
||||
void Focus() override {}
|
||||
bool HasFocus() override;
|
||||
uint32_t GetCaptureSequenceNumber() const override;
|
||||
bool IsSurfaceAvailableForCopy(void) override;
|
||||
void Hide(void) override;
|
||||
bool IsShowing(void) override;
|
||||
bool IsSurfaceAvailableForCopy() override;
|
||||
void Hide() override;
|
||||
bool IsShowing() override;
|
||||
void EnsureSurfaceSynchronizedForWebTest() override;
|
||||
gfx::Rect GetViewBounds(void) override;
|
||||
gfx::Rect GetViewBounds() override;
|
||||
gfx::Size GetVisibleViewportSize() override;
|
||||
void SetInsets(const gfx::Insets&) override {}
|
||||
void SetBackgroundColor(SkColor color) override;
|
||||
@@ -107,7 +107,7 @@ class OffScreenRenderWidgetHostView
|
||||
bool request_unadjusted_movement) override;
|
||||
blink::mojom::PointerLockResult ChangePointerLock(
|
||||
bool request_unadjusted_movement) override;
|
||||
void UnlockPointer(void) override {}
|
||||
void UnlockPointer() override {}
|
||||
void TakeFallbackContentFrom(content::RenderWidgetHostView* view) override;
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
void SetActive(bool active) override {}
|
||||
@@ -135,10 +135,10 @@ class OffScreenRenderWidgetHostView
|
||||
void SetIsLoading(bool is_loading) override {}
|
||||
void TextInputStateChanged(const ui::mojom::TextInputState& params) override {
|
||||
}
|
||||
void ImeCancelComposition(void) override {}
|
||||
void ImeCancelComposition() override {}
|
||||
void RenderProcessGone() override;
|
||||
void ShowWithVisibility(content::PageVisibilityState page_visibility) final;
|
||||
void Destroy(void) override;
|
||||
void Destroy() override;
|
||||
void UpdateTooltipUnderCursor(const std::u16string&) override {}
|
||||
input::CursorManager* GetCursorManager() override;
|
||||
void CopyFromSurface(
|
||||
@@ -147,7 +147,7 @@ class OffScreenRenderWidgetHostView
|
||||
base::OnceCallback<void(const SkBitmap&)> callback) override;
|
||||
display::ScreenInfo GetScreenInfo() const override;
|
||||
void TransformPointToRootSurface(gfx::PointF* point) override {}
|
||||
gfx::Rect GetBoundsInRootWindow(void) override;
|
||||
gfx::Rect GetBoundsInRootWindow() override;
|
||||
std::optional<content::DisplayFeature> GetDisplayFeature() override;
|
||||
void SetDisplayFeatureForTesting(
|
||||
const content::DisplayFeature* display_feature) override {}
|
||||
|
||||
@@ -110,17 +110,18 @@ SerialChooserController::SerialChooserController(
|
||||
content::SerialChooser::Callback callback,
|
||||
content::WebContents* web_contents,
|
||||
base::WeakPtr<ElectronSerialDelegate> serial_delegate)
|
||||
: WebContentsObserver(web_contents),
|
||||
: web_contents_{web_contents ? web_contents->GetWeakPtr()
|
||||
: base::WeakPtr<content::WebContents>()},
|
||||
filters_(std::move(filters)),
|
||||
allowed_bluetooth_service_class_ids_(
|
||||
std::move(allowed_bluetooth_service_class_ids)),
|
||||
callback_(std::move(callback)),
|
||||
serial_delegate_(serial_delegate),
|
||||
render_frame_host_id_(render_frame_host->GetGlobalId()) {
|
||||
origin_ = web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
|
||||
origin_ = web_contents_->GetPrimaryMainFrame()->GetLastCommittedOrigin();
|
||||
|
||||
chooser_context_ = SerialChooserContextFactory::GetForBrowserContext(
|
||||
web_contents->GetBrowserContext())
|
||||
web_contents_->GetBrowserContext())
|
||||
->AsWeakPtr();
|
||||
DCHECK(chooser_context_);
|
||||
chooser_context_->GetPortManager()->GetDevices(base::BindOnce(
|
||||
@@ -133,10 +134,10 @@ SerialChooserController::~SerialChooserController() {
|
||||
}
|
||||
|
||||
api::Session* SerialChooserController::GetSession() {
|
||||
if (!web_contents()) {
|
||||
if (!web_contents_) {
|
||||
return nullptr;
|
||||
}
|
||||
return api::Session::FromBrowserContext(web_contents()->GetBrowserContext());
|
||||
return api::Session::FromBrowserContext(web_contents_->GetBrowserContext());
|
||||
}
|
||||
|
||||
void SerialChooserController::OnPortAdded(
|
||||
@@ -148,7 +149,7 @@ void SerialChooserController::OnPortAdded(
|
||||
|
||||
api::Session* session = GetSession();
|
||||
if (session) {
|
||||
session->Emit("serial-port-added", port.Clone(), web_contents());
|
||||
session->Emit("serial-port-added", port.Clone(), web_contents_.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,10 +158,8 @@ void SerialChooserController::OnPortRemoved(
|
||||
const auto it = std::ranges::find(ports_, port.token,
|
||||
&device::mojom::SerialPortInfo::token);
|
||||
if (it != ports_.end()) {
|
||||
api::Session* session = GetSession();
|
||||
if (session) {
|
||||
session->Emit("serial-port-removed", port.Clone(), web_contents());
|
||||
}
|
||||
if (api::Session* session = GetSession())
|
||||
session->Emit("serial-port-removed", port.Clone(), web_contents_.get());
|
||||
ports_.erase(it);
|
||||
}
|
||||
}
|
||||
@@ -203,10 +202,9 @@ void SerialChooserController::OnGetDevices(
|
||||
}
|
||||
|
||||
bool prevent_default = false;
|
||||
api::Session* session = GetSession();
|
||||
if (session) {
|
||||
if (api::Session* session = GetSession()) {
|
||||
prevent_default = session->Emit(
|
||||
"select-serial-port", ports_, web_contents(),
|
||||
"select-serial-port", ports_, web_contents_.get(),
|
||||
base::BindRepeating(&SerialChooserController::OnDeviceChosen,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "base/scoped_observation.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
#include "content/public/browser/serial_chooser.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "services/device/public/mojom/serial.mojom-forward.h"
|
||||
#include "shell/browser/serial/serial_chooser_context.h"
|
||||
#include "third_party/blink/public/mojom/serial/serial.mojom-forward.h"
|
||||
@@ -32,8 +31,7 @@ class ElectronSerialDelegate;
|
||||
|
||||
// SerialChooserController provides data for the Serial API permission prompt.
|
||||
class SerialChooserController final
|
||||
: private SerialChooserContext::PortObserver,
|
||||
private content::WebContentsObserver {
|
||||
: private SerialChooserContext::PortObserver {
|
||||
public:
|
||||
SerialChooserController(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
@@ -64,6 +62,8 @@ class SerialChooserController final
|
||||
void RunCallback(device::mojom::SerialPortInfoPtr port);
|
||||
void OnDeviceChosen(const std::string& port_id);
|
||||
|
||||
base::WeakPtr<content::WebContents> web_contents_;
|
||||
|
||||
std::vector<blink::mojom::SerialPortFilterPtr> filters_;
|
||||
std::vector<::device::BluetoothUUID> allowed_bluetooth_service_class_ids_;
|
||||
content::SerialChooser::Callback callback_;
|
||||
|
||||
@@ -15,6 +15,8 @@ DelayedNativeViewHost::~DelayedNativeViewHost() = default;
|
||||
|
||||
void DelayedNativeViewHost::ViewHierarchyChanged(
|
||||
const views::ViewHierarchyChangedDetails& details) {
|
||||
if (!details.is_add && native_view())
|
||||
Detach();
|
||||
NativeViewHost::ViewHierarchyChanged(details);
|
||||
if (details.is_add && GetWidget() && !native_view())
|
||||
Attach(native_view_);
|
||||
|
||||
@@ -156,17 +156,14 @@ bool FillFileInfoWithNode(Archive::FileInfo* info,
|
||||
|
||||
} // namespace
|
||||
|
||||
IntegrityPayload::IntegrityPayload()
|
||||
: algorithm(HashAlgorithm::kNone), block_size(0) {}
|
||||
IntegrityPayload::IntegrityPayload() = default;
|
||||
IntegrityPayload::~IntegrityPayload() = default;
|
||||
IntegrityPayload::IntegrityPayload(const IntegrityPayload& other) = default;
|
||||
|
||||
Archive::FileInfo::FileInfo()
|
||||
: unpacked(false), executable(false), size(0), offset(0) {}
|
||||
Archive::FileInfo::FileInfo() = default;
|
||||
Archive::FileInfo::~FileInfo() = default;
|
||||
|
||||
Archive::Archive(const base::FilePath& path)
|
||||
: initialized_(false), path_(path), file_(base::File::FILE_OK) {
|
||||
Archive::Archive(const base::FilePath& path) : path_{path} {
|
||||
electron::ScopedAllowBlockingForElectron allow_blocking;
|
||||
file_.Initialize(path_, base::File::FLAG_OPEN | base::File::FLAG_READ);
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
|
||||
@@ -31,9 +31,9 @@ struct IntegrityPayload {
|
||||
IntegrityPayload();
|
||||
~IntegrityPayload();
|
||||
IntegrityPayload(const IntegrityPayload& other);
|
||||
HashAlgorithm algorithm;
|
||||
HashAlgorithm algorithm = HashAlgorithm::kNone;
|
||||
std::string hash;
|
||||
uint32_t block_size;
|
||||
uint32_t block_size = 0U;
|
||||
std::vector<std::string> blocks;
|
||||
};
|
||||
|
||||
@@ -44,10 +44,10 @@ class Archive {
|
||||
struct FileInfo {
|
||||
FileInfo();
|
||||
~FileInfo();
|
||||
bool unpacked;
|
||||
bool executable;
|
||||
uint32_t size;
|
||||
uint64_t offset;
|
||||
bool unpacked = false;
|
||||
bool executable = false;
|
||||
uint32_t size = 0U;
|
||||
uint64_t offset = 0U;
|
||||
std::optional<IntegrityPayload> integrity;
|
||||
};
|
||||
|
||||
@@ -100,10 +100,10 @@ class Archive {
|
||||
base::FilePath path() const { return path_; }
|
||||
|
||||
private:
|
||||
bool initialized_;
|
||||
bool initialized_ = false;
|
||||
bool header_validated_ = false;
|
||||
const base::FilePath path_;
|
||||
base::File file_;
|
||||
base::File file_{base::File::FILE_OK};
|
||||
int fd_ = -1;
|
||||
uint32_t header_size_ = 0;
|
||||
std::optional<base::Value::Dict> header_;
|
||||
|
||||
@@ -126,11 +126,8 @@ bool ReadFileToString(const base::FilePath& path, std::string* contents) {
|
||||
return false;
|
||||
|
||||
contents->resize(info.size);
|
||||
if (static_cast<int>(info.size) !=
|
||||
src.Read(info.offset, const_cast<char*>(contents->data()),
|
||||
contents->size())) {
|
||||
if (!src.ReadAndCheck(info.offset, base::as_writable_byte_span(*contents)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info.integrity)
|
||||
ValidateIntegrityOrDie(base::as_byte_span(*contents), *info.integrity);
|
||||
|
||||
@@ -47,11 +47,11 @@ class DeleteFileProgressSink : public IFileOperationProgressSink {
|
||||
|
||||
private:
|
||||
// IFileOperationProgressSink
|
||||
ULONG STDMETHODCALLTYPE AddRef(void) override;
|
||||
ULONG STDMETHODCALLTYPE Release(void) override;
|
||||
ULONG STDMETHODCALLTYPE AddRef() override;
|
||||
ULONG STDMETHODCALLTYPE Release() override;
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
|
||||
LPVOID* ppvObj) override;
|
||||
HRESULT STDMETHODCALLTYPE StartOperations(void) override;
|
||||
HRESULT STDMETHODCALLTYPE StartOperations() override;
|
||||
HRESULT STDMETHODCALLTYPE FinishOperations(HRESULT) override;
|
||||
HRESULT STDMETHODCALLTYPE PreRenameItem(DWORD, IShellItem*, LPCWSTR) override;
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
@@ -90,9 +90,9 @@ class DeleteFileProgressSink : public IFileOperationProgressSink {
|
||||
HRESULT,
|
||||
IShellItem*) override;
|
||||
HRESULT STDMETHODCALLTYPE UpdateProgress(UINT, UINT) override;
|
||||
HRESULT STDMETHODCALLTYPE ResetTimer(void) override;
|
||||
HRESULT STDMETHODCALLTYPE PauseTimer(void) override;
|
||||
HRESULT STDMETHODCALLTYPE ResumeTimer(void) override;
|
||||
HRESULT STDMETHODCALLTYPE ResetTimer() override;
|
||||
HRESULT STDMETHODCALLTYPE PauseTimer() override;
|
||||
HRESULT STDMETHODCALLTYPE ResumeTimer() override;
|
||||
|
||||
ULONG m_cRef;
|
||||
};
|
||||
|
||||
@@ -116,6 +116,14 @@ describe('BrowserWindow module', () => {
|
||||
await closed;
|
||||
});
|
||||
|
||||
it('should work if called when multiple messageBoxes are showing', async () => {
|
||||
const closed = once(w, 'closed');
|
||||
dialog.showMessageBox(w, { message: 'Hello Error' });
|
||||
dialog.showMessageBox(w, { message: 'Hello Error' });
|
||||
w.close();
|
||||
await closed;
|
||||
});
|
||||
|
||||
it('closes window without rounded corners', async () => {
|
||||
await closeWindow(w);
|
||||
w = new BrowserWindow({ show: false, frame: false, roundedCorners: false });
|
||||
|
||||
@@ -9,8 +9,12 @@
|
||||
import { expect } from 'chai';
|
||||
import * as dbus from 'dbus-native';
|
||||
import { app } from 'electron/main';
|
||||
import { nativeImage } from 'electron/common';
|
||||
import { ifdescribe } from './lib/spec-helpers';
|
||||
import { promisify } from 'node:util';
|
||||
import * as path from 'node:path';
|
||||
|
||||
const fixturesPath = path.join(__dirname, 'fixtures');
|
||||
|
||||
const skip = process.platform !== 'linux' ||
|
||||
process.arch === 'ia32' ||
|
||||
@@ -92,6 +96,7 @@ ifdescribe(!skip)('Notification module (dbus)', () => {
|
||||
title: 'title',
|
||||
subtitle: 'subtitle',
|
||||
body: 'body',
|
||||
icon: nativeImage.createFromPath(path.join(fixturesPath, 'assets', 'notification_icon.png')),
|
||||
replyPlaceholder: 'replyPlaceholder',
|
||||
sound: 'sound',
|
||||
closeButtonText: 'closeButtonText'
|
||||
@@ -117,7 +122,9 @@ ifdescribe(!skip)('Notification module (dbus)', () => {
|
||||
actions: [],
|
||||
hints: {
|
||||
append: 'true',
|
||||
image_data: [3, 3, 12, true, 8, 4, Buffer.from([255, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 76, 255, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 38, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0])],
|
||||
'desktop-entry': appName,
|
||||
'sender-pid': process.pid,
|
||||
urgency: 1
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1206,6 +1206,22 @@ describe('webContents module', () => {
|
||||
expect(currentFocused).to.be.true();
|
||||
expect(childFocused).to.be.false();
|
||||
});
|
||||
|
||||
it('does not crash when focusing a WebView webContents', async () => {
|
||||
const w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
webviewTag: true
|
||||
}
|
||||
});
|
||||
|
||||
w.show();
|
||||
await w.loadURL('data:text/html,<webview src="data:text/html,hi"></webview>');
|
||||
|
||||
const wc = webContents.getAllWebContents().find((wc) => wc.getType() === 'webview')!;
|
||||
expect(() => wc.focus()).to.not.throw();
|
||||
});
|
||||
});
|
||||
|
||||
const moveFocusToDevTools = async (win: BrowserWindow) => {
|
||||
|
||||
BIN
spec/fixtures/assets/notification_icon.png
vendored
Normal file
BIN
spec/fixtures/assets/notification_icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 107 B |
Reference in New Issue
Block a user