node-gtk 3.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/binding.gyp +21 -0
- package/lib/bootstrap.js +43 -11
- package/lib/loop.js +13 -1
- package/lib/overrides/Gtk-4.0.js +6 -27
- package/package.json +1 -2
- package/src/boxed.cc +13 -5
- package/src/function.cc +12 -5
- package/src/fundamental.cc +451 -0
- package/src/fundamental.h +71 -0
- package/src/gi.cc +11 -1
- package/src/gobject.cc +100 -8
- package/src/gobject.h +2 -0
- package/src/modules/cairo/context.cc +103 -103
- package/src/modules/cairo/font-extents.cc +6 -2
- package/src/modules/cairo/generator.js +1 -1
- package/src/modules/cairo/glyph.cc +6 -2
- package/src/modules/cairo/path.cc +6 -2
- package/src/modules/cairo/rectangle-int.cc +6 -2
- package/src/modules/cairo/rectangle.cc +6 -2
- package/src/modules/cairo/text-cluster.cc +6 -2
- package/src/modules/cairo/text-extents.cc +6 -2
- package/src/modules/system.cc +4 -4
- package/src/util.h +3 -3
- package/src/value.cc +44 -8
- package/src/value.h +2 -2
package/src/gobject.cc
CHANGED
|
@@ -40,6 +40,11 @@ static Nan::Persistent<FunctionTemplate> baseTemplate;
|
|
|
40
40
|
// this makes registerClass() optional. Empty until JS installs it.
|
|
41
41
|
static Nan::Persistent<Function> lazyClassRegister;
|
|
42
42
|
|
|
43
|
+
// JS callback invoked the first time a private/non-introspectable concrete type
|
|
44
|
+
// (eg GLocalFile) is wrapped, to mix its implemented interfaces' methods into
|
|
45
|
+
// the class prototype. Installed via SetInterfaceMethodsApplier. See issue #441.
|
|
46
|
+
static Nan::Persistent<Function> interfaceMethodsApplier;
|
|
47
|
+
|
|
43
48
|
|
|
44
49
|
static MaybeLocal<FunctionTemplate> GetClassTemplate(GType gtype);
|
|
45
50
|
static MaybeLocal<Function> GetClass(GType gtype);
|
|
@@ -170,7 +175,7 @@ static void ToggleNotify(gpointer user_data, GObject *gobject, gboolean toggle_d
|
|
|
170
175
|
}
|
|
171
176
|
|
|
172
177
|
static void AssociateGObject(Local<Object> object, GObject *gobject, GType gtype) {
|
|
173
|
-
object
|
|
178
|
+
Nan::SetInternalFieldPointer(object, 0, gobject);
|
|
174
179
|
|
|
175
180
|
SET_OBJECT_GTYPE(object, gtype);
|
|
176
181
|
|
|
@@ -226,7 +231,13 @@ static void GObjectConstructor(const FunctionCallbackInfo<Value> &info) {
|
|
|
226
231
|
|
|
227
232
|
/* User code calling `new Gtk.Widget({ ... })` */
|
|
228
233
|
|
|
234
|
+
// Nan provides Nan::SetPrototype but no GetPrototype wrapper, and V8 14
|
|
235
|
+
// renamed Object::GetPrototype() to GetPrototypeV2().
|
|
236
|
+
#if defined(V8_MAJOR_VERSION) && V8_MAJOR_VERSION >= 14
|
|
237
|
+
Local<Object> proto = Nan::To<Object>(self->GetPrototypeV2()).ToLocalChecked();
|
|
238
|
+
#else
|
|
229
239
|
Local<Object> proto = Nan::To<Object>(self->GetPrototype()).ToLocalChecked();
|
|
240
|
+
#endif
|
|
230
241
|
|
|
231
242
|
/* A JS subclass (`class Foo extends Gtk.Widget {}`) that was never passed to
|
|
232
243
|
* registerClass() owns no GType: `__gtype__` is only *inherited* from its
|
|
@@ -360,15 +371,23 @@ static void GObjectClassDestroyed(const Nan::WeakCallbackInfo<GType> &info) {
|
|
|
360
371
|
(V8_MAJOR_VERSION == 12 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION > 4))
|
|
361
372
|
#define PROPERTY_CALLBACK_RETURN_TYPE v8::Intercepted
|
|
362
373
|
#define PROPERTY_CALLBACK_INFO_TYPE v8::PropertyCallbackInfo<void>
|
|
374
|
+
#define PROPERTY_CALLBACK_INFO_VALUE_TYPE void
|
|
375
|
+
#define PROPERTY_CALLBACK_IS_INTERCEPTED 1
|
|
363
376
|
#else
|
|
364
377
|
#define PROPERTY_CALLBACK_RETURN_TYPE void
|
|
365
378
|
#define PROPERTY_CALLBACK_INFO_TYPE v8::PropertyCallbackInfo<Value>
|
|
379
|
+
#define PROPERTY_CALLBACK_INFO_VALUE_TYPE Value
|
|
380
|
+
#define PROPERTY_CALLBACK_IS_INTERCEPTED 0
|
|
366
381
|
#endif
|
|
367
382
|
|
|
368
383
|
static PROPERTY_CALLBACK_RETURN_TYPE
|
|
369
384
|
GObjectFallbackPropertyGetter(Local<v8::Name> property,
|
|
370
385
|
const v8::PropertyCallbackInfo<Value>& info) {
|
|
371
|
-
|
|
386
|
+
// V8 14 removed PropertyCallbackInfo::Holder(); the Nan wrapper's Holder()
|
|
387
|
+
// aliases HolderV2() on new V8 and Holder() on older V8. The handler is
|
|
388
|
+
// installed on InstanceTemplate, so the holder is the instance.
|
|
389
|
+
Nan::PropertyCallbackInfo<Value> nanInfo(info, info.Data());
|
|
390
|
+
auto self = nanInfo.Holder();
|
|
372
391
|
GObject *gobject = GObjectFromWrapper (self);
|
|
373
392
|
|
|
374
393
|
g_assert(gobject != NULL);
|
|
@@ -398,7 +417,8 @@ GObjectFallbackPropertyGetter(Local<v8::Name> property,
|
|
|
398
417
|
static PROPERTY_CALLBACK_RETURN_TYPE
|
|
399
418
|
GObjectFallbackPropertySetter(Local<v8::Name> property, Local<Value> value,
|
|
400
419
|
const PROPERTY_CALLBACK_INFO_TYPE& info) {
|
|
401
|
-
|
|
420
|
+
Nan::PropertyCallbackInfo<PROPERTY_CALLBACK_INFO_VALUE_TYPE> nanInfo(info, info.Data());
|
|
421
|
+
auto self = nanInfo.Holder();
|
|
402
422
|
GObject *gobject = GNodeJS::GObjectFromWrapper (self);
|
|
403
423
|
|
|
404
424
|
Nan::Utf8String prop_name_v (TO_STRING (property));
|
|
@@ -425,8 +445,16 @@ GObjectFallbackPropertySetter(Local<v8::Name> property, Local<Value> value,
|
|
|
425
445
|
return Nan::Intercepted::No();
|
|
426
446
|
} else {
|
|
427
447
|
// Property exists. Whether we can convert the value and set the
|
|
428
|
-
// property or not, consider the set
|
|
448
|
+
// property or not, consider the set handled.
|
|
449
|
+
#if !PROPERTY_CALLBACK_IS_INTERCEPTED
|
|
450
|
+
// Non-intercepted API (V8 <= 12.4): signal "handled" by setting the
|
|
451
|
+
// return value. Without it V8 falls through and defines a shadowing
|
|
452
|
+
// own-property on the wrapper, masking the interceptor getter (e.g. a
|
|
453
|
+
// 64-bit property would then read back as a Number, not a BigInt).
|
|
429
454
|
RETURN(value);
|
|
455
|
+
#endif
|
|
456
|
+
// Intercepted API (V8 > 12.4): the info is <void>, so signal via the
|
|
457
|
+
// Intercepted return value rather than by setting a return value.
|
|
430
458
|
g_free(prop_name);
|
|
431
459
|
return Nan::Intercepted::Yes();
|
|
432
460
|
}
|
|
@@ -500,7 +528,8 @@ static Local<v8::Private> SignalHandlersKey(v8::Isolate *isolate) {
|
|
|
500
528
|
|
|
501
529
|
// Append a handler to the wrapper's handler array, returning its index.
|
|
502
530
|
static guint AddSignalHandler(Local<Object> wrapper, Local<Function> handler) {
|
|
503
|
-
|
|
531
|
+
// Object::GetIsolate() was removed in V8 14; use the current isolate.
|
|
532
|
+
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
|
504
533
|
Local<v8::Context> context = isolate->GetCurrentContext();
|
|
505
534
|
Local<v8::Private> key = SignalHandlersKey(isolate);
|
|
506
535
|
|
|
@@ -533,7 +562,7 @@ Local<Value> GetSignalHandler(GObject *gobject, guint index) {
|
|
|
533
562
|
if (object.IsEmpty())
|
|
534
563
|
return Local<Value>();
|
|
535
564
|
|
|
536
|
-
v8::Isolate *isolate =
|
|
565
|
+
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
|
537
566
|
Local<v8::Context> context = isolate->GetCurrentContext();
|
|
538
567
|
Local<Value> handlers =
|
|
539
568
|
object->GetPrivate(context, SignalHandlersKey(isolate)).ToLocalChecked();
|
|
@@ -719,7 +748,7 @@ NAN_METHOD(GObjectToString) {
|
|
|
719
748
|
|
|
720
749
|
const char* typeName = g_type_name(type);
|
|
721
750
|
char *className = *Nan::Utf8String(self->GetConstructorName());
|
|
722
|
-
void *address = self
|
|
751
|
+
void *address = Nan::GetInternalFieldPointer(self, 0);
|
|
723
752
|
|
|
724
753
|
char *str = g_strdup_printf("[%s:%s %#zx]", typeName, className, (size_t)address);
|
|
725
754
|
|
|
@@ -782,6 +811,60 @@ static MaybeLocal<FunctionTemplate> NewClassTemplate (GType gtype) {
|
|
|
782
811
|
return MaybeLocal<FunctionTemplate> (tpl);
|
|
783
812
|
}
|
|
784
813
|
|
|
814
|
+
/*
|
|
815
|
+
* Mix the methods of a type's implemented interfaces into its class prototype.
|
|
816
|
+
*
|
|
817
|
+
* Introspectable object types get this for free: makeObject() in JS iterates
|
|
818
|
+
* their interfaces and installs the methods. Private/non-introspectable concrete
|
|
819
|
+
* types (eg GLocalFile, which implements the public GFile interface) are never
|
|
820
|
+
* seen by makeObject(), so their instances would only expose the base GObject
|
|
821
|
+
* methods. Here we enumerate the type's introspectable interfaces and hand them
|
|
822
|
+
* to the JS `interfaceMethodsApplier`, which reuses makeInterface()/define() to
|
|
823
|
+
* install the methods (and property accessors) on the class prototype.
|
|
824
|
+
*
|
|
825
|
+
* See issue #441.
|
|
826
|
+
*/
|
|
827
|
+
static void ApplyInterfaceMethods(Local<Function> constructor, GType gtype) {
|
|
828
|
+
if (interfaceMethodsApplier.IsEmpty())
|
|
829
|
+
return;
|
|
830
|
+
|
|
831
|
+
guint n_interfaces = 0;
|
|
832
|
+
GType *interfaces = g_type_interfaces(gtype, &n_interfaces);
|
|
833
|
+
|
|
834
|
+
Local<Array> refs = New<Array>();
|
|
835
|
+
uint32_t count = 0;
|
|
836
|
+
for (guint i = 0; i < n_interfaces; i++) {
|
|
837
|
+
GIBaseInfo *iface_info = g_irepository_find_by_gtype(NULL, interfaces[i]);
|
|
838
|
+
if (iface_info == NULL)
|
|
839
|
+
continue;
|
|
840
|
+
if (g_base_info_get_type(iface_info) == GI_INFO_TYPE_INTERFACE) {
|
|
841
|
+
Local<Object> ref = New<Object>();
|
|
842
|
+
Nan::Set(ref, UTF8("namespace"), UTF8(g_base_info_get_namespace(iface_info)));
|
|
843
|
+
Nan::Set(ref, UTF8("name"), UTF8(g_base_info_get_name(iface_info)));
|
|
844
|
+
Nan::Set(refs, count++, ref);
|
|
845
|
+
}
|
|
846
|
+
g_base_info_unref(iface_info);
|
|
847
|
+
}
|
|
848
|
+
g_free(interfaces);
|
|
849
|
+
|
|
850
|
+
if (count == 0)
|
|
851
|
+
return;
|
|
852
|
+
|
|
853
|
+
Local<Function> applier = New<Function>(interfaceMethodsApplier);
|
|
854
|
+
Local<Value> argv[] = { constructor, refs };
|
|
855
|
+
Nan::TryCatch tryCatch;
|
|
856
|
+
Nan::Call(applier, Nan::GetCurrentContext()->Global(), 2, argv);
|
|
857
|
+
if (tryCatch.HasCaught()) {
|
|
858
|
+
Nan::Utf8String message(tryCatch.Exception());
|
|
859
|
+
g_warning("node-gtk: could not apply interface methods for %s: %s",
|
|
860
|
+
g_type_name(gtype), *message);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
NAN_METHOD(SetInterfaceMethodsApplier) {
|
|
865
|
+
interfaceMethodsApplier.Reset(info[0].As<Function>());
|
|
866
|
+
}
|
|
867
|
+
|
|
785
868
|
static MaybeLocal<FunctionTemplate> GetClassTemplate(GType gtype) {
|
|
786
869
|
void *data = g_type_get_qdata (gtype, GNodeJS::template_quark());
|
|
787
870
|
|
|
@@ -809,6 +892,15 @@ static MaybeLocal<FunctionTemplate> GetClassTemplate(GType gtype) {
|
|
|
809
892
|
g_type_set_qdata(gtype, GNodeJS::template_quark(), persistentTpl);
|
|
810
893
|
g_type_set_qdata(gtype, GNodeJS::function_quark(), persistentFn);
|
|
811
894
|
|
|
895
|
+
// Introspectable object types have their interface methods installed by
|
|
896
|
+
// makeObject() in JS. Private concrete types are never seen there, so mix
|
|
897
|
+
// in their interface methods now (issue #441).
|
|
898
|
+
GIBaseInfo *own_info = g_irepository_find_by_gtype(NULL, gtype);
|
|
899
|
+
if (own_info == NULL)
|
|
900
|
+
ApplyInterfaceMethods(fn, gtype);
|
|
901
|
+
else
|
|
902
|
+
g_base_info_unref(own_info);
|
|
903
|
+
|
|
812
904
|
return MaybeLocal<FunctionTemplate> (tpl);
|
|
813
905
|
}
|
|
814
906
|
|
|
@@ -889,7 +981,7 @@ GObject * GObjectFromWrapper(Local<Value> value) {
|
|
|
889
981
|
|
|
890
982
|
Local<Object> object = TO_OBJECT (value);
|
|
891
983
|
|
|
892
|
-
void *ptr = object
|
|
984
|
+
void *ptr = Nan::GetInternalFieldPointer(object, 0);
|
|
893
985
|
GObject *gobject = G_OBJECT (ptr);
|
|
894
986
|
return gobject;
|
|
895
987
|
}
|
package/src/gobject.h
CHANGED
|
@@ -23,6 +23,8 @@ Local<FunctionTemplate> GetBaseClassTemplate ();
|
|
|
23
23
|
MaybeLocal<Value> GetGObjectProperty (GObject * gobject, const char *prop_name);
|
|
24
24
|
MaybeLocal<v8::Boolean> SetGObjectProperty (GObject * gobject, const char *prop_name, Local<Value> value);
|
|
25
25
|
|
|
26
|
+
NAN_METHOD(SetInterfaceMethodsApplier);
|
|
27
|
+
|
|
26
28
|
namespace ObjectClass {
|
|
27
29
|
|
|
28
30
|
NAN_METHOD(SetLazyClassRegister);
|