refactor: ginify desktopCapturer (#22746)
This commit is contained in:
parent
9aa27e1709
commit
a824e12275
5 changed files with 54 additions and 28 deletions
|
@ -1,5 +1,3 @@
|
|||
import { EventEmitter } from 'events'
|
||||
|
||||
const { createDesktopCapturer } = process.electronBinding('desktop_capturer')
|
||||
|
||||
const deepEqual = (a: ElectronInternal.GetSourcesOptions, b: ElectronInternal.GetSourcesOptions) => JSON.stringify(a) === JSON.stringify(b)
|
||||
|
@ -23,21 +21,20 @@ export const getSources = (event: Electron.IpcMainEvent, options: ElectronIntern
|
|||
|
||||
const stopRunning = () => {
|
||||
if (capturer) {
|
||||
capturer.emit = null
|
||||
delete capturer._onerror
|
||||
delete capturer._onfinished
|
||||
capturer = null
|
||||
}
|
||||
// Remove from currentlyRunning once we resolve or reject
|
||||
currentlyRunning = currentlyRunning.filter(running => running.options !== options)
|
||||
}
|
||||
|
||||
const emitter = new EventEmitter()
|
||||
|
||||
emitter.once('error', (event, error: string) => {
|
||||
capturer._onerror = (error: string) => {
|
||||
stopRunning()
|
||||
reject(error)
|
||||
})
|
||||
}
|
||||
|
||||
emitter.once('finished', (event, sources: Electron.DesktopCapturerSource[], fetchWindowIcons: boolean) => {
|
||||
capturer._onfinished = (sources: Electron.DesktopCapturerSource[], fetchWindowIcons: boolean) => {
|
||||
stopRunning()
|
||||
resolve(sources.map(source => ({
|
||||
id: source.id,
|
||||
|
@ -46,9 +43,8 @@ export const getSources = (event: Electron.IpcMainEvent, options: ElectronIntern
|
|||
display_id: source.display_id,
|
||||
appIcon: (fetchWindowIcons && source.appIcon) ? source.appIcon.toDataURL() : null
|
||||
})))
|
||||
})
|
||||
}
|
||||
|
||||
capturer.emit = emitter.emit.bind(emitter)
|
||||
capturer.startHandling(options.captureWindow, options.captureScreen, options.thumbnailSize, options.fetchWindowIcons)
|
||||
|
||||
// If the WebContents is destroyed before receiving result, just remove the
|
||||
|
|
|
@ -14,10 +14,11 @@
|
|||
#include "chrome/browser/media/webrtc/desktop_media_list.h"
|
||||
#include "chrome/browser/media/webrtc/window_icon_util.h"
|
||||
#include "content/public/browser/desktop_capture.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "shell/common/api/electron_api_native_image.h"
|
||||
#include "shell/common/gin_converters/gfx_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
|
||||
|
@ -59,9 +60,9 @@ namespace electron {
|
|||
|
||||
namespace api {
|
||||
|
||||
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
}
|
||||
gin::WrapperInfo DesktopCapturer::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {}
|
||||
|
||||
DesktopCapturer::~DesktopCapturer() = default;
|
||||
|
||||
|
@ -154,7 +155,7 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
|||
// |media_list_sources|.
|
||||
if (!webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
|
||||
&device_names)) {
|
||||
Emit("error", "Failed to get sources.");
|
||||
gin_helper::CallMethod(this, "_onerror", "Failed to get sources.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -184,7 +185,8 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
|||
}
|
||||
|
||||
if (!capture_window_ && !capture_screen_)
|
||||
Emit("finished", captured_sources_, fetch_window_icons_);
|
||||
gin_helper::CallMethod(this, "_onfinished", captured_sources_,
|
||||
fetch_window_icons_);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -192,15 +194,16 @@ gin::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
|||
return gin::CreateHandle(isolate, new DesktopCapturer(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void DesktopCapturer::BuildPrototype(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "DesktopCapturer"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
gin::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return gin::Wrappable<DesktopCapturer>::GetObjectTemplateBuilder(isolate)
|
||||
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
||||
}
|
||||
|
||||
const char* DesktopCapturer::GetTypeName() {
|
||||
return "DesktopCapturer";
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
|
||||
#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/common/gin_helper/trackable_object.h"
|
||||
#include "gin/wrappable.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace api {
|
||||
|
||||
class DesktopCapturer : public gin_helper::TrackableObject<DesktopCapturer>,
|
||||
class DesktopCapturer : public gin::Wrappable<DesktopCapturer>,
|
||||
public DesktopMediaListObserver {
|
||||
public:
|
||||
struct Source {
|
||||
|
@ -32,14 +32,17 @@ class DesktopCapturer : public gin_helper::TrackableObject<DesktopCapturer>,
|
|||
|
||||
static gin::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
void StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size,
|
||||
bool fetch_window_icons);
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
protected:
|
||||
explicit DesktopCapturer(v8::Isolate* isolate);
|
||||
~DesktopCapturer() override;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "gin/converter.h"
|
||||
#include "gin/wrappable.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
|
@ -63,6 +64,28 @@ v8::Local<v8::Value> CustomEmit(v8::Isolate* isolate,
|
|||
&converted_args);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
v8::Local<v8::Value> CallMethod(v8::Isolate* isolate,
|
||||
gin::Wrappable<T>* object,
|
||||
const char* method_name,
|
||||
Args&&... args) {
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Object> v8_object;
|
||||
if (object->GetWrapper(isolate).ToLocal(&v8_object))
|
||||
return CustomEmit(isolate, v8_object, method_name,
|
||||
std::forward<Args>(args)...);
|
||||
else
|
||||
return v8::Local<v8::Value>();
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
v8::Local<v8::Value> CallMethod(gin::Wrappable<T>* object,
|
||||
const char* method_name,
|
||||
Args&&... args) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
return CallMethod(isolate, object, method_name, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace gin_helper
|
||||
|
||||
#endif // SHELL_COMMON_GIN_HELPER_EVENT_EMITTER_CALLER_H_
|
||||
|
|
3
typings/internal-electron.d.ts
vendored
3
typings/internal-electron.d.ts
vendored
|
@ -94,7 +94,8 @@ declare namespace ElectronInternal {
|
|||
|
||||
interface DesktopCapturer {
|
||||
startHandling(captureWindow: boolean, captureScreen: boolean, thumbnailSize: Electron.Size, fetchWindowIcons: boolean): void;
|
||||
emit: typeof NodeJS.EventEmitter.prototype.emit | null;
|
||||
_onerror: (error: string) => void;
|
||||
_onfinished: (sources: Electron.DesktopCapturerSource[], fetchWindowIcons: boolean) => void;
|
||||
}
|
||||
|
||||
interface GetSourcesOptions {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue