summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Welsh <contact@evanwelsh.com>2022-05-22 13:43:23 -0700
committerEvan Welsh <contact@evanwelsh.com>2022-05-22 13:43:23 -0700
commit6671f83d8614ed355f03389ad692b0a6ab3fea7b (patch)
tree7e839e4ec54ad3268d738f2e2649ed3d3ee1b4c0
parent6ab6db38fe5a45979167d2b6f0cadd06a772798f (diff)
downloadgjs-ewlsh/fix-reentrancy-issues-private-lib.tar.gz
overrides: Allow re-entrancy in GLib importsewlsh/fix-reentrancy-issues-private-lib
-rw-r--r--gi/repo.cpp7
-rw-r--r--gjs/engine.cpp23
-rw-r--r--modules/core/overrides/GLib.js420
-rw-r--r--modules/core/overrides/GObject.js978
-rw-r--r--modules/core/overrides/Gio.js347
-rw-r--r--modules/core/overrides/Gtk.js268
-rw-r--r--modules/core/overrides/cairo.js6
7 files changed, 1031 insertions, 1018 deletions
diff --git a/gi/repo.cpp b/gi/repo.cpp
index 9f5d4e1f..f09b4f80 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -551,9 +551,10 @@ lookup_override_function(JSContext *cx,
goto fail;
}
- if (!gjs_object_require_property(cx, module, "override module",
- atoms.init(), function) ||
- !function.isObjectOrNull()) {
+ if (!JS_GetPropertyById(cx, module, atoms.init(), function))
+ return false;
+
+ if (!function.isUndefined() && !function.isObjectOrNull()) {
gjs_throw(cx, "Unexpected value for _init in overrides module");
goto fail;
}
diff --git a/gjs/engine.cpp b/gjs/engine.cpp
index 16d84cc1..bd66a79b 100644
--- a/gjs/engine.cpp
+++ b/gjs/engine.cpp
@@ -79,7 +79,9 @@ class GjsSourceHook : public js::SourceHook {
#ifdef G_OS_WIN32
HMODULE gjs_dll;
-static bool gjs_is_inited = false;
+static bool _gjs_is_inited = false;
+
+static bool gjs_is_inited() { return _gjs_is_inited; }
BOOL WINAPI
DllMain (HINSTANCE hinstDLL,
@@ -90,7 +92,11 @@ LPVOID lpvReserved)
{
case DLL_PROCESS_ATTACH:
gjs_dll = hinstDLL;
- gjs_is_inited = JS_Init();
+
+ if (!JS_Init())
+ g_error("Could not initialize Javascript");
+
+ _gjs_is_inited = true;
break;
case DLL_THREAD_DETACH:
@@ -104,7 +110,6 @@ LPVOID lpvReserved)
return TRUE;
}
-
#else
class GjsInit {
public:
@@ -116,15 +121,19 @@ public:
~GjsInit() {
JS_ShutDown();
}
-
- explicit operator bool() const { return true; }
};
-static GjsInit gjs_is_inited;
+static bool gjs_is_inited() {
+ // In C++11 static function variables are guaranteed to only be
+ // initialized once.
+ static GjsInit gjs_is_inited;
+
+ return true;
+}
#endif
JSContext* gjs_create_js_context(GjsContextPrivate* uninitialized_gjs) {
- g_assert(gjs_is_inited);
+ g_assert(gjs_is_inited());
JSContext *cx = JS_NewContext(32 * 1024 * 1024 /* max bytes */);
if (!cx)
return nullptr;
diff --git a/modules/core/overrides/GLib.js b/modules/core/overrides/GLib.js
index cb8f177e..ed6005ba 100644
--- a/modules/core/overrides/GLib.js
+++ b/modules/core/overrides/GLib.js
@@ -2,8 +2,8 @@
// SPDX-FileCopyrightText: 2011 Giovanni Campagna
const ByteArray = imports.byteArray;
-
-let GLib;
+const {GLib, GjsPrivate} = imports.gi;
+const {log_set_writer_func, log_set_writer_default} = GjsPrivate;
const SIMPLE_TYPES = ['b', 'y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd', 's', 'o', 'g'];
@@ -256,71 +256,66 @@ function _escapeCharacterSetChars(char) {
return char;
}
-function _init() {
- // this is imports.gi.GLib
-
- GLib = this;
-
- // For convenience in property min or max values, since GLib.MAXINT64 and
- // friends will log a warning when used
- this.MAXINT64_BIGINT = 0x7fff_ffff_ffff_ffffn;
- this.MININT64_BIGINT = -this.MAXINT64_BIGINT - 1n;
- this.MAXUINT64_BIGINT = 0xffff_ffff_ffff_ffffn;
-
- // small HACK: we add a matches() method to standard Errors so that
- // you can do "if (e.matches(Ns.FooError, Ns.FooError.SOME_CODE))"
- // without checking instanceof
- Error.prototype.matches = function () {
- return false;
- };
-
- // Guard against domains that aren't valid quarks and would lead
- // to a crash
- const quarkToString = this.quark_to_string;
- const realNewLiteral = this.Error.new_literal;
- this.Error.new_literal = function (domain, code, message) {
- if (quarkToString(domain) === null)
- throw new TypeError(`Error.new_literal: ${domain} is not a valid domain`);
- return realNewLiteral(domain, code, message);
- };
-
- this.Variant._new_internal = function (sig, value) {
- let signature = Array.prototype.slice.call(sig);
-
- let variant = _packVariant(signature, value);
- if (signature.length !== 0)
- throw new TypeError('Invalid GVariant signature (more than one single complete type)');
-
- return variant;
- };
-
- // Deprecate version of new GLib.Variant()
- this.Variant.new = function (sig, value) {
- return new GLib.Variant(sig, value);
- };
- this.Variant.prototype.unpack = function () {
- return _unpackVariant(this, false);
- };
- this.Variant.prototype.deepUnpack = function () {
- return _unpackVariant(this, true);
- };
- // backwards compatibility alias
- this.Variant.prototype.deep_unpack = this.Variant.prototype.deepUnpack;
-
- // Note: discards type information, if the variant contains any 'v' types
- this.Variant.prototype.recursiveUnpack = function () {
- return _unpackVariant(this, true, true);
- };
-
- this.Variant.prototype.toString = function () {
- return `[object variant of type "${this.get_type_string()}"]`;
- };
-
- this.Bytes.prototype.toArray = function () {
- return imports._byteArrayNative.fromGBytes(this);
- };
-
- this.log_structured =
+// For convenience in property min or max values, since GLib.MAXINT64 and
+// friends will log a warning when used
+GLib.MAXINT64_BIGINT = 0x7fff_ffff_ffff_ffffn;
+GLib.MININT64_BIGINT = -GLib.MAXINT64_BIGINT - 1n;
+GLib.MAXUINT64_BIGINT = 0xffff_ffff_ffff_ffffn;
+
+// small HACK: we add a matches() method to standard Errors so that
+// you can do "if (e.matches(Ns.FooError, Ns.FooError.SOME_CODE))"
+// without checking instanceof
+Error.prototype.matches = function () {
+ return false;
+};
+
+// Guard against domains that aren't valid quarks and would lead
+// to a crash
+const quarkToString = GLib.quark_to_string;
+const realNewLiteral = GLib.Error.new_literal;
+GLib.Error.new_literal = function (domain, code, message) {
+ if (quarkToString(domain) === null)
+ throw new TypeError(`Error.new_literal: ${domain} is not a valid domain`);
+ return realNewLiteral(domain, code, message);
+};
+
+GLib.Variant._new_internal = function (sig, value) {
+ let signature = Array.prototype.slice.call(sig);
+
+ let variant = _packVariant(signature, value);
+ if (signature.length !== 0)
+ throw new TypeError('Invalid GVariant signature (more than one single complete type)');
+
+ return variant;
+};
+
+// Deprecate version of new GLib.Variant()
+GLib.Variant.new = function (sig, value) {
+ return new GLib.Variant(sig, value);
+};
+GLib.Variant.prototype.unpack = function () {
+ return _unpackVariant(this, false);
+};
+GLib.Variant.prototype.deepUnpack = function () {
+ return _unpackVariant(this, true);
+};
+// backwards compatibility alias
+GLib.Variant.prototype.deep_unpack = GLib.Variant.prototype.deepUnpack;
+
+// Note: discards type information, if the variant contains any 'v' types
+GLib.Variant.prototype.recursiveUnpack = function () {
+ return _unpackVariant(this, true, true);
+};
+
+GLib.Variant.prototype.toString = function () {
+ return `[object variant of type "${GLib.get_type_string()}"]`;
+};
+
+GLib.Bytes.prototype.toArray = function () {
+ return imports._byteArrayNative.fromGBytes(this);
+};
+
+GLib.log_structured =
/**
* @param {string} logDomain
* @param {GLib.LogLevelFlags} logLevel
@@ -353,156 +348,147 @@ function _init() {
GLib.log_variant(logDomain, logLevel, new GLib.Variant('a{sv}', fields));
};
- // GjsPrivate depends on GLib so we cannot import it
- // before GLib is fully resolved.
-
- this.log_set_writer_func_variant = function (...args) {
- const {log_set_writer_func} = imports.gi.GjsPrivate;
-
- log_set_writer_func(...args);
- };
-
- this.log_set_writer_default = function (...args) {
- const {log_set_writer_default} = imports.gi.GjsPrivate;
-
- log_set_writer_default(...args);
- };
-
- this.log_set_writer_func = function (writer_func) {
- const {log_set_writer_func} = imports.gi.GjsPrivate;
-
- if (typeof writer_func !== 'function') {
- log_set_writer_func(writer_func);
- } else {
- log_set_writer_func(function (logLevel, stringFields) {
- const stringFieldsObj = {...stringFields.recursiveUnpack()};
- return writer_func(logLevel, stringFieldsObj);
- });
- }
- };
-
- this.VariantDict.prototype.lookup = function (key, variantType = null, deep = false) {
- if (typeof variantType === 'string')
- variantType = new GLib.VariantType(variantType);
+GLib.log_set_writer_func_variant = function (...args) {
+ log_set_writer_func(...args);
+};
- const variant = this.lookup_value(key, variantType);
- if (variant === null)
- return null;
- return _unpackVariant(variant, deep);
- };
-
- // Prevent user code from calling GLib string manipulation functions that
- // return the same string that was passed in. These can't be annotated
- // properly, and will mostly crash.
- // Here we provide approximate implementations of the functions so that if
- // they had happened to work in the past, they will continue working, but
- // log a stack trace and a suggestion of what to use instead.
- // Exceptions are thrown instead for GLib.stpcpy() of which the return value
- // is useless anyway and GLib.ascii_formatd() which is too complicated to
- // implement here.
-
- this.stpcpy = function () {
- throw _notIntrospectableError('GLib.stpcpy()', 'the + operator');
- };
-
- this.strstr_len = function (haystack, len, needle) {
- _warnNotIntrospectable('GLib.strstr_len()', 'String.indexOf()');
- let searchString = haystack;
- if (len !== -1)
- searchString = searchString.slice(0, len);
- const index = searchString.indexOf(needle);
- if (index === -1)
- return null;
- return haystack.slice(index);
- };
-
- this.strrstr = function (haystack, needle) {
- _warnNotIntrospectable('GLib.strrstr()', 'String.lastIndexOf()');
- const index = haystack.lastIndexOf(needle);
- if (index === -1)
- return null;
- return haystack.slice(index);
- };
-
- this.strrstr_len = function (haystack, len, needle) {
- _warnNotIntrospectable('GLib.strrstr_len()', 'String.lastIndexOf()');
- let searchString = haystack;
- if (len !== -1)
- searchString = searchString.slice(0, len);
- const index = searchString.lastIndexOf(needle);
- if (index === -1)
- return null;
- return haystack.slice(index);
- };
-
- this.strup = function (string) {
- _warnNotIntrospectable('GLib.strup()',
- 'String.toUpperCase() or GLib.ascii_strup()');
- return string.toUpperCase();
- };
-
- this.strdown = function (string) {
- _warnNotIntrospectable('GLib.strdown()',
- 'String.toLowerCase() or GLib.ascii_strdown()');
- return string.toLowerCase();
- };
-
- this.strreverse = function (string) {
- _warnNotIntrospectable('GLib.strreverse()',
- 'Array.reverse() and String.join()');
- return [...string].reverse().join('');
- };
-
- this.ascii_dtostr = function (unused, len, number) {
- _warnNotIntrospectable('GLib.ascii_dtostr()', 'JS string conversion');
- return `${number}`.slice(0, len);
- };
+GLib.log_set_writer_default = function (...args) {
+ log_set_writer_default(...args);
+};
- this.ascii_formatd = function () {
- throw _notIntrospectableError('GLib.ascii_formatd()',
- 'Number.toExponential() and string interpolation');
- };
-
- this.strchug = function (string) {
- _warnNotIntrospectable('GLib.strchug()', 'String.trimStart()');
- return string.trimStart();
- };
-
- this.strchomp = function (string) {
- _warnNotIntrospectable('GLib.strchomp()', 'String.trimEnd()');
- return string.trimEnd();
- };
-
- // g_strstrip() is a macro and therefore doesn't even appear in the GIR
- // file, but we may as well include it here since it's trivial
- this.strstrip = function (string) {
- _warnNotIntrospectable('GLib.strstrip()', 'String.trim()');
- return string.trim();
- };
-
- this.strdelimit = function (string, delimiters, newDelimiter) {
- _warnNotIntrospectable('GLib.strdelimit()', 'String.replace()');
-
- if (delimiters === null)
- delimiters = GLib.STR_DELIMITERS;
- if (typeof newDelimiter === 'number')
- newDelimiter = String.fromCharCode(newDelimiter);
-
- const delimiterChars = delimiters.split('');
- const escapedDelimiterChars = delimiterChars.map(_escapeCharacterSetChars);
- const delimiterRegex = new RegExp(`[${escapedDelimiterChars.join('')}]`, 'g');
- return string.replace(delimiterRegex, newDelimiter);
- };
-
- this.strcanon = function (string, validChars, substitutor) {
- _warnNotIntrospectable('GLib.strcanon()', 'String.replace()');
-
- if (typeof substitutor === 'number')
- substitutor = String.fromCharCode(substitutor);
+GLib.log_set_writer_func = function (writer_func) {
+ if (typeof writer_func !== 'function') {
+ log_set_writer_func(writer_func);
+ } else {
+ log_set_writer_func(function (logLevel, stringFields) {
+ const stringFieldsObj = {...stringFields.recursiveUnpack()};
+ return writer_func(logLevel, stringFieldsObj);
+ });
+ }
+};
+
+GLib.VariantDict.prototype.lookup = function (key, variantType = null, deep = false) {
+ if (typeof variantType === 'string')
+ variantType = new GLib.VariantType(variantType);
+
+ const variant = this.lookup_value(key, variantType);
+ if (variant === null)
+ return null;
+ return _unpackVariant(variant, deep);
+};
+
+// Prevent user code from calling GLib string manipulation functions that
+// return the same string that was passed in. These can't be annotated
+// properly, and will mostly crash.
+// Here we provide approximate implementations of the functions so that if
+// they had happened to work in the past, they will continue working, but
+// log a stack trace and a suggestion of what to use instead.
+// Exceptions are thrown instead for GLib.stpcpy() of which the return value
+// is useless anyway and GLib.ascii_formatd() which is too complicated to
+// implement here.
+
+GLib.stpcpy = function () {
+ throw _notIntrospectableError('GLib.stpcpy()', 'the + operator');
+};
+
+GLib.strstr_len = function (haystack, len, needle) {
+ _warnNotIntrospectable('GLib.strstr_len()', 'String.indexOf()');
+ let searchString = haystack;
+ if (len !== -1)
+ searchString = searchString.slice(0, len);
+ const index = searchString.indexOf(needle);
+ if (index === -1)
+ return null;
+ return haystack.slice(index);
+};
+
+GLib.strrstr = function (haystack, needle) {
+ _warnNotIntrospectable('GLib.strrstr()', 'String.lastIndexOf()');
+ const index = haystack.lastIndexOf(needle);
+ if (index === -1)
+ return null;
+ return haystack.slice(index);
+};
+
+GLib.strrstr_len = function (haystack, len, needle) {
+ _warnNotIntrospectable('GLib.strrstr_len()', 'String.lastIndexOf()');
+ let searchString = haystack;
+ if (len !== -1)
+ searchString = searchString.slice(0, len);
+ const index = searchString.lastIndexOf(needle);
+ if (index === -1)
+ return null;
+ return haystack.slice(index);
+};
+
+GLib.strup = function (string) {
+ _warnNotIntrospectable('GLib.strup()',
+ 'String.toUpperCase() or GLib.ascii_strup()');
+ return string.toUpperCase();
+};
+
+GLib.strdown = function (string) {
+ _warnNotIntrospectable('GLib.strdown()',
+ 'String.toLowerCase() or GLib.ascii_strdown()');
+ return string.toLowerCase();
+};
+
+GLib.strreverse = function (string) {
+ _warnNotIntrospectable('GLib.strreverse()',
+ 'Array.reverse() and String.join()');
+ return [...string].reverse().join('');
+};
+
+GLib.ascii_dtostr = function (unused, len, number) {
+ _warnNotIntrospectable('GLib.ascii_dtostr()', 'JS string conversion');
+ return `${number}`.slice(0, len);
+};
+
+GLib.ascii_formatd = function () {
+ throw _notIntrospectableError('GLib.ascii_formatd()',
+ 'Number.toExponential() and string interpolation');
+};
+
+GLib.strchug = function (string) {
+ _warnNotIntrospectable('GLib.strchug()', 'String.trimStart()');
+ return string.trimStart();
+};
+
+GLib.strchomp = function (string) {
+ _warnNotIntrospectable('GLib.strchomp()', 'String.trimEnd()');
+ return string.trimEnd();
+};
+
+// g_strstrip() is a macro and therefore doesn't even appear in the GIR
+// file, but we may as well include it here since it's trivial
+GLib.strstrip = function (string) {
+ _warnNotIntrospectable('GLib.strstrip()', 'String.trim()');
+ return string.trim();
+};
+
+GLib.strdelimit = function (string, delimiters, newDelimiter) {
+ _warnNotIntrospectable('GLib.strdelimit()', 'String.replace()');
+
+ if (delimiters === null)
+ delimiters = GLib.STR_DELIMITERS;
+ if (typeof newDelimiter === 'number')
+ newDelimiter = String.fromCharCode(newDelimiter);
+
+ const delimiterChars = delimiters.split('');
+ const escapedDelimiterChars = delimiterChars.map(_escapeCharacterSetChars);
+ const delimiterRegex = new RegExp(`[${escapedDelimiterChars.join('')}]`, 'g');
+ return string.replace(delimiterRegex, newDelimiter);
+};
+
+GLib.strcanon = function (string, validChars, substitutor) {
+ _warnNotIntrospectable('GLib.strcanon()', 'String.replace()');
+
+ if (typeof substitutor === 'number')
+ substitutor = String.fromCharCode(substitutor);
+
+ const validArray = validChars.split('');
+ const escapedValidArray = validArray.map(_escapeCharacterSetChars);
+ const invalidRegex = new RegExp(`[^${escapedValidArray.join('')}]`, 'g');
+ return string.replace(invalidRegex, substitutor);
+};
- const validArray = validChars.split('');
- const escapedValidArray = validArray.map(_escapeCharacterSetChars);
- const invalidRegex = new RegExp(`[^${escapedValidArray.join('')}]`, 'g');
- return string.replace(invalidRegex, substitutor);
- };
-}
diff --git a/modules/core/overrides/GObject.js b/modules/core/overrides/GObject.js
index df6f9dc2..76168bf7 100644
--- a/modules/core/overrides/GObject.js
+++ b/modules/core/overrides/GObject.js
@@ -4,12 +4,10 @@
// SPDX-FileCopyrightText: 2017 Philip Chimento <philip.chimento@gmail.com>, <philip@endlessm.com>
const Gi = imports._gi;
-const {GjsPrivate, GLib} = imports.gi;
+const {GjsPrivate, GLib, GObject} = imports.gi;
const {_checkAccessors, _registerType} = imports._common;
const Legacy = imports._legacy;
-let GObject;
-
var GTypeName = Symbol('GType name');
var GTypeFlags = Symbol('GType flags');
var interfaces = Symbol('GObject interfaces');
@@ -281,277 +279,276 @@ function _checkProperties(klass) {
_checkAccessors(klass.prototype, pspec, GObject);
}
-function _init() {
- GObject = this;
- function _makeDummyClass(obj, name, upperName, gtypeName, actual) {
- let gtype = GObject.type_from_name(gtypeName);
- obj[`TYPE_${upperName}`] = gtype;
- obj[name] = function (v) {
- return actual(v);
- };
- obj[name].$gtype = gtype;
- }
- GObject.gtypeNameBasedOnJSPath = false;
+function _makeDummyClass(obj, name, upperName, gtypeName, actual) {
+ let gtype = GObject.type_from_name(gtypeName);
+ obj[`TYPE_${upperName}`] = gtype;
+ obj[name] = function (v) {
+ return actual(v);
+ };
+ obj[name].$gtype = gtype;
+}
- _makeDummyClass(GObject, 'VoidType', 'NONE', 'void', function () {});
- _makeDummyClass(GObject, 'Char', 'CHAR', 'gchar', Number);
- _makeDummyClass(GObject, 'UChar', 'UCHAR', 'guchar', Number);
- _makeDummyClass(GObject, 'Unichar', 'UNICHAR', 'gint', String);
+GObject.gtypeNameBasedOnJSPath = false;
- GObject.TYPE_BOOLEAN = GObject.type_from_name('gboolean');
- GObject.Boolean = Boolean;
- Boolean.$gtype = GObject.TYPE_BOOLEAN;
+_makeDummyClass(GObject, 'VoidType', 'NONE', 'void', function () {});
+_makeDummyClass(GObject, 'Char', 'CHAR', 'gchar', Number);
+_makeDummyClass(GObject, 'UChar', 'UCHAR', 'guchar', Number);
+_makeDummyClass(GObject, 'Unichar', 'UNICHAR', 'gint', String);
- _makeDummyClass(GObject, 'Int', 'INT', 'gint', Number);
- _makeDummyClass(GObject, 'UInt', 'UINT', 'guint', Number);
- _makeDummyClass(GObject, 'Long', 'LONG', 'glong', Number);
- _makeDummyClass(GObject, 'ULong', 'ULONG', 'gulong', Number);
- _makeDummyClass(GObject, 'Int64', 'INT64', 'gint64', Number);
- _makeDummyClass(GObject, 'UInt64', 'UINT64', 'guint64', Number);
+GObject.TYPE_BOOLEAN = GObject.type_from_name('gboolean');
+GObject.Boolean = Boolean;
+Boolean.$gtype = GObject.TYPE_BOOLEAN;
- GObject.TYPE_ENUM = GObject.type_from_name('GEnum');
- GObject.TYPE_FLAGS = GObject.type_from_name('GFlags');
+_makeDummyClass(GObject, 'Int', 'INT', 'gint', Number);
+_makeDummyClass(GObject, 'UInt', 'UINT', 'guint', Number);
+_makeDummyClass(GObject, 'Long', 'LONG', 'glong', Number);
+_makeDummyClass(GObject, 'ULong', 'ULONG', 'gulong', Number);
+_makeDummyClass(GObject, 'Int64', 'INT64', 'gint64', Number);
+_makeDummyClass(GObject, 'UInt64', 'UINT64', 'guint64', Number);
- _makeDummyClass(GObject, 'Float', 'FLOAT', 'gfloat', Number);
- GObject.TYPE_DOUBLE = GObject.type_from_name('gdouble');
- GObject.Double = Number;
- Number.$gtype = GObject.TYPE_DOUBLE;
+GObject.TYPE_ENUM = GObject.type_from_name('GEnum');
+GObject.TYPE_FLAGS = GObject.type_from_name('GFlags');
- GObject.TYPE_STRING = GObject.type_from_name('gchararray');
- GObject.String = String;
- String.$gtype = GObject.TYPE_STRING;
+_makeDummyClass(GObject, 'Float', 'FLOAT', 'gfloat', Number);
+GObject.TYPE_DOUBLE = GObject.type_from_name('gdouble');
+GObject.Double = Number;
+Number.$gtype = GObject.TYPE_DOUBLE;
- GObject.TYPE_JSOBJECT = GObject.type_from_name('JSObject');
- GObject.JSObject = Object;
- Object.$gtype = GObject.TYPE_JSOBJECT;
+GObject.TYPE_STRING = GObject.type_from_name('gchararray');
+GObject.String = String;
+String.$gtype = GObject.TYPE_STRING;
- GObject.TYPE_POINTER = GObject.type_from_name('gpointer');
- GObject.TYPE_BOXED = GObject.type_from_name('GBoxed');
- GObject.TYPE_PARAM = GObject.type_from_name('GParam');
- GObject.TYPE_INTERFACE = GObject.type_from_name('GInterface');
- GObject.TYPE_OBJECT = GObject.type_from_name('GObject');
- GObject.TYPE_VARIANT = GObject.type_from_name('GVariant');
+GObject.TYPE_JSOBJECT = GObject.type_from_name('JSObject');
+GObject.JSObject = Object;
+Object.$gtype = GObject.TYPE_JSOBJECT;
- _makeDummyClass(GObject, 'Type', 'GTYPE', 'GType', GObject.type_from_name);
+GObject.TYPE_POINTER = GObject.type_from_name('gpointer');
+GObject.TYPE_BOXED = GObject.type_from_name('GBoxed');
+GObject.TYPE_PARAM = GObject.type_from_name('GParam');
+GObject.TYPE_INTERFACE = GObject.type_from_name('GInterface');
+GObject.TYPE_OBJECT = GObject.type_from_name('GObject');
+GObject.TYPE_VARIANT = GObject.type_from_name('GVariant');
- GObject.ParamSpec.char = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
- return GObject.param_spec_char(name, nick, blurb, minimum, maximum, defaultValue, flags);
- };
+_makeDummyClass(GObject, 'Type', 'GTYPE', 'GType', GObject.type_from_name);
- GObject.ParamSpec.uchar = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
- return GObject.param_spec_uchar(name, nick, blurb, minimum, maximum, defaultValue, flags);
- };
+GObject.ParamSpec.char = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
+ return GObject.param_spec_char(name, nick, blurb, minimum, maximum, defaultValue, flags);
+};
- GObject.ParamSpec.int = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
- return GObject.param_spec_int(name, nick, blurb, minimum, maximum, defaultValue, flags);
- };
+GObject.ParamSpec.uchar = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
+ return GObject.param_spec_uchar(name, nick, blurb, minimum, maximum, defaultValue, flags);
+};
- GObject.ParamSpec.uint = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
- return GObject.param_spec_uint(name, nick, blurb, minimum, maximum, defaultValue, flags);
- };
+GObject.ParamSpec.int = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
+ return GObject.param_spec_int(name, nick, blurb, minimum, maximum, defaultValue, flags);
+};
- GObject.ParamSpec.long = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
- return GObject.param_spec_long(name, nick, blurb, minimum, maximum, defaultValue, flags);
- };
+GObject.ParamSpec.uint = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
+ return GObject.param_spec_uint(name, nick, blurb, minimum, maximum, defaultValue, flags);
+};
- GObject.ParamSpec.ulong = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
- return GObject.param_spec_ulong(name, nick, blurb, minimum, maximum, defaultValue, flags);
- };
+GObject.ParamSpec.long = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
+ return GObject.param_spec_long(name, nick, blurb, minimum, maximum, defaultValue, flags);
+};
- GObject.ParamSpec.int64 = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
- return GObject.param_spec_int64(name, nick, blurb, minimum, maximum, defaultValue, flags);
- };
+GObject.ParamSpec.ulong = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
+ return GObject.param_spec_ulong(name, nick, blurb, minimum, maximum, defaultValue, flags);
+};
- GObject.ParamSpec.uint64 = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
- return GObject.param_spec_uint64(name, nick, blurb, minimum, maximum, defaultValue, flags);
- };
+GObject.ParamSpec.int64 = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
+ return GObject.param_spec_int64(name, nick, blurb, minimum, maximum, defaultValue, flags);
+};
- GObject.ParamSpec.float = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
- return GObject.param_spec_float(name, nick, blurb, minimum, maximum, defaultValue, flags);
- };
+GObject.ParamSpec.uint64 = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
+ return GObject.param_spec_uint64(name, nick, blurb, minimum, maximum, defaultValue, flags);
+};
- GObject.ParamSpec.boolean = function (name, nick, blurb, flags, defaultValue) {
- return GObject.param_spec_boolean(name, nick, blurb, defaultValue, flags);
- };
+GObject.ParamSpec.float = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
+ return GObject.param_spec_float(name, nick, blurb, minimum, maximum, defaultValue, flags);
+};
- GObject.ParamSpec.flags = function (name, nick, blurb, flags, flagsType, defaultValue) {
- return GObject.param_spec_flags(name, nick, blurb, flagsType, defaultValue, flags);
- };
+GObject.ParamSpec.boolean = function (name, nick, blurb, flags, defaultValue) {
+ return GObject.param_spec_boolean(name, nick, blurb, defaultValue, flags);
+};
- GObject.ParamSpec.enum = function (name, nick, blurb, flags, enumType, defaultValue) {
- return GObject.param_spec_enum(name, nick, blurb, enumType, defaultValue, flags);
- };
+GObject.ParamSpec.flags = function (name, nick, blurb, flags, flagsType, defaultValue) {
+ return GObject.param_spec_flags(name, nick, blurb, flagsType, defaultValue, flags);
+};
- GObject.ParamSpec.double = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
- return GObject.param_spec_double(name, nick, blurb, minimum, maximum, defaultValue, flags);
- };
+GObject.ParamSpec.enum = function (name, nick, blurb, flags, enumType, defaultValue) {
+ return GObject.param_spec_enum(name, nick, blurb, enumType, defaultValue, flags);
+};
- GObject.ParamSpec.string = function (name, nick, blurb, flags, defaultValue) {
- return GObject.param_spec_string(name, nick, blurb, defaultValue, flags);
- };
+GObject.ParamSpec.double = function (name, nick, blurb, flags, minimum, maximum, defaultValue) {
+ return GObject.param_spec_double(name, nick, blurb, minimum, maximum, defaultValue, flags);
+};
- GObject.ParamSpec.boxed = function (name, nick, blurb, flags, boxedType) {
- return GObject.param_spec_boxed(name, nick, blurb, boxedType, flags);
- };
+GObject.ParamSpec.string = function (name, nick, blurb, flags, defaultValue) {
+ return GObject.param_spec_string(name, nick, blurb, defaultValue, flags);
+};
- GObject.ParamSpec.object = function (name, nick, blurb, flags, objectType) {
- return GObject.param_spec_object(name, nick, blurb, objectType, flags);
- };
+GObject.ParamSpec.boxed = function (name, nick, blurb, flags, boxedType) {
+ return GObject.param_spec_boxed(name, nick, blurb, boxedType, flags);
+};
+
+GObject.ParamSpec.object = function (name, nick, blurb, flags, objectType) {
+ return GObject.param_spec_object(name, nick, blurb, objectType, flags);
+};
- GObject.ParamSpec.jsobject = function (name, nick, blurb, flags) {
- return GObject.param_spec_boxed(name, nick, blurb, Object.$gtype, flags);
- };
+GObject.ParamSpec.jsobject = function (name, nick, blurb, flags) {
+ return GObject.param_spec_boxed(name, nick, blurb, Object.$gtype, flags);
+};
- GObject.ParamSpec.param = function (name, nick, blurb, flags, paramType) {
- return GObject.param_spec_param(name, nick, blurb, paramType, flags);
- };
+GObject.ParamSpec.param = function (name, nick, blurb, flags, paramType) {
+ return GObject.param_spec_param(name, nick, blurb, paramType, flags);
+};
- GObject.ParamSpec.override = Gi.override_property;
+GObject.ParamSpec.override = Gi.override_property;
- Object.defineProperties(GObject.ParamSpec.prototype, {
- 'name': {
- configurable: false,
- enumerable: false,
- get() {
- return this.get_name();
- },
+Object.defineProperties(GObject.ParamSpec.prototype, {
+ 'name': {
+ configurable: false,
+ enumerable: false,
+ get() {
+ return this.get_name();
},
- '_nick': {
- configurable: false,
- enumerable: false,
- get() {
- return this.get_nick();
- },
+ },
+ '_nick': {
+ configurable: false,
+ enumerable: false,
+ get() {
+ return this.get_nick();
},
- 'nick': {
- configurable: false,
- enumerable: false,
- get() {
- return this.get_nick();
- },
+ },
+ 'nick': {
+ configurable: false,
+ enumerable: false,
+ get() {
+ return this.get_nick();
},
- '_blurb': {
- configurable: false,
- enumerable: false,
- get() {
- return this.get_blurb();
- },
+ },
+ '_blurb': {
+ configurable: false,
+ enumerable: false,
+ get() {
+ return this.get_blurb();
},
- 'blurb': {
- configurable: false,
- enumerable: false,
- get() {
- return this.get_blurb();
- },
+ },
+ 'blurb': {
+ configurable: false,
+ enumerable: false,
+ get() {
+ return this.get_blurb();
},
- 'default_value': {
- configurable: false,
- enumerable: false,
- get() {
- return this.get_default_value();
- },
+ },
+ 'default_value': {
+ configurable: false,
+ enumerable: false,
+ get() {
+ return this.get_default_value();
},
- 'flags': {
- configurable: false,
- enumerable: false,
- get() {
- return GjsPrivate.param_spec_get_flags(this);
- },
+ },
+ 'flags': {
+ configurable: false,
+ enumerable: false,
+ get() {
+ return GjsPrivate.param_spec_get_flags(this);
},
- 'value_type': {
- configurable: false,
- enumerable: false,
- get() {
- return GjsPrivate.param_spec_get_value_type(this);
- },
+ },
+ 'value_type': {
+ configurable: false,
+ enumerable: false,
+ get() {
+ return GjsPrivate.param_spec_get_value_type(this);
},
- 'owner_type': {
- configurable: false,
- enumerable: false,
- get() {
- return GjsPrivate.param_spec_get_owner_type(this);
- },
+ },
+ 'owner_type': {
+ configurable: false,
+ enumerable: false,
+ get() {
+ return GjsPrivate.param_spec_get_owner_type(this);
},
- });
+ },
+});
- let {GObjectMeta, GObjectInterface} = Legacy.defineGObjectLegacyObjects(GObject);
- GObject.Class = GObjectMeta;
- GObject.Interface = GObjectInterface;
- GObject.Object.prototype.__metaclass__ = GObject.Class;
+let {GObjectMeta, GObjectInterface} = Legacy.defineGObjectLegacyObjects(GObject);
+GObject.Class = GObjectMeta;
+GObject.Interface = GObjectInterface;
+GObject.Object.prototype.__metaclass__ = GObject.Class;
- // For compatibility with Lang.Class... we need a _construct
- // or the Lang.Class constructor will fail.
- GObject.Object.prototype._construct = function (...args) {
- this._init(...args);
- return this;
- };
+// For compatibility with Lang.Class... we need a _construct
+// or the Lang.Class constructor will fail.
+GObject.Object.prototype._construct = function (...args) {
+ this._init(...args);
+ return this;
+};
- GObject.registerClass = registerClass;
+GObject.registerClass = registerClass;
- GObject.Object.new = function (gtype, props = {}) {
- const constructor = Gi.lookupConstructor(gtype);
+GObject.Object.new = function (gtype, props = {}) {
+ const constructor = Gi.lookupConstructor(gtype);
- if (!constructor)
- throw new Error(`Constructor for gtype ${gtype} not found`);
- return new constructor(props);
- };
+ if (!constructor)
+ throw new Error(`Constructor for gtype ${gtype} not found`);
+ return new constructor(props);
+};
- GObject.Object.new_with_properties = function (gtype, names, values) {
- if (!Array.isArray(names) || !Array.isArray(values))
- throw new Error('new_with_properties takes two arrays (names, values)');
- if (names.length !== values.length)
- throw new Error('Arrays passed to new_with_properties must be the same length');
+GObject.Object.new_with_properties = function (gtype, names, values) {
+ if (!Array.isArray(names) || !Array.isArray(values))
+ throw new Error('new_with_properties takes two arrays (names, values)');
+ if (names.length !== values.length)
+ throw new Error('Arrays passed to new_with_properties must be the same length');
- const props = Object.fromEntries(names.map((name, ix) => [name, values[ix]]));
- return GObject.Object.new(gtype, props);
- };
+ const props = Object.fromEntries(names.map((name, ix) => [name, values[ix]]));
+ return GObject.Object.new(gtype, props);
+};
- GObject.Object._classInit = function (klass) {
- _checkProperties(klass);
+GObject.Object._classInit = function (klass) {
+ _checkProperties(klass);
- if (_registerType in klass)
- klass[_registerType]();
- else
- _resolveLegacyClassFunction(klass, _registerType).call(klass);
+ if (_registerType in klass)
+ klass[_registerType]();
+ else
+ _resolveLegacyClassFunction(klass, _registerType).call(klass);
- return klass;
- };
+ return klass;
+};
- // For backwards compatibility only. Use instanceof instead.
- GObject.Object.implements = function (iface) {
- if (iface.$gtype)
- return GObject.type_is_a(this, iface.$gtype);
- return false;
- };
+// For backwards compatibility only. Use instanceof instead.
+GObject.Object.implements = function (iface) {
+ if (iface.$gtype)
+ return GObject.type_is_a(this, iface.$gtype);
+ return false;
+};
- function registerGObjectType() {
- let klass = this;
+function registerGObjectType() {
+ let klass = this;
- let gtypename = _createGTypeName(klass);
- let gflags = klass.hasOwnProperty(GTypeFlags) ? klass[GTypeFlags] : 0;
- let gobjectInterfaces = klass.hasOwnProperty(interfaces) ? klass[interfaces] : [];
- let propertiesArray = _propertiesAsArray(klass);
- let parent = Object.getPrototypeOf(klass);
- let gobjectSignals = klass.hasOwnProperty(signals) ? klass[signals] : [];
+ let gtypename = _createGTypeName(klass);
+ let gflags = klass.hasOwnProperty(GTypeFlags) ? klass[GTypeFlags] : 0;
+ let gobjectInterfaces = klass.hasOwnProperty(interfaces) ? klass[interfaces] : [];
+ let propertiesArray = _propertiesAsArray(klass);
+ let parent = Object.getPrototypeOf(klass);
+ let gobjectSignals = klass.hasOwnProperty(signals) ? klass[signals] : [];
- // Default to the GObject-specific prototype, fallback on the JS prototype for GI native classes.
- const parentPrototype = parent.prototype[Gi.gobject_prototype_symbol] ?? parent.prototype;
+ // Default to the GObject-specific prototype, fallback on the JS prototype for GI native classes.
+ const parentPrototype = parent.prototype[Gi.gobject_prototype_symbol] ?? parent.prototype;
- const [giPrototype, registeredType] = Gi.register_type_with_class(
- klass, parentPrototype, gtypename, gflags,
- gobjectInterfaces, propertiesArray);
+ const [giPrototype, registeredType] = Gi.register_type_with_class(
+ klass, parentPrototype, gtypename, gflags,
+ gobjectInterfaces, propertiesArray);
- _defineGType(klass, giPrototype, registeredType);
- _createSignals(klass.$gtype, gobjectSignals);
+ _defineGType(klass, giPrototype, registeredType);
+ _createSignals(klass.$gtype, gobjectSignals);
- // Reverse the interface array to give the last required interface precedence over the first.
- const requiredInterfaces = [...gobjectInterfaces].reverse();
- requiredInterfaces.forEach(iface =>
- _copyInterfacePrototypeDescriptors(klass.prototype, iface.prototype));
+ // Reverse the interface array to give the last required interface precedence over the first.
+ const requiredInterfaces = [...gobjectInterfaces].reverse();
+ requiredInterfaces.forEach(iface =>
+ _copyInterfacePrototypeDescriptors(klass.prototype, iface.prototype));
- Object.getOwnPropertyNames(klass.prototype)
+ Object.getOwnPropertyNames(klass.prototype)
.filter(name => name.startsWith('vfunc_') || name.startsWith('on_'))
.forEach(name => {
let descr = Object.getOwnPropertyDescriptor(klass.prototype, name);
@@ -575,64 +572,64 @@ function _init() {
}
});
- gobjectInterfaces.forEach(iface =>
- _checkInterface(iface, klass.prototype));
+ gobjectInterfaces.forEach(iface =>
+ _checkInterface(iface, klass.prototype));
- // Lang.Class parent classes don't support static inheritance
- if (!('implements' in klass))
- klass.implements = GObject.Object.implements;
- }
+ // Lang.Class parent classes don't support static inheritance
+ if (!('implements' in klass))
+ klass.implements = GObject.Object.implements;
+}
- Object.defineProperty(GObject.Object, _registerType, {
- value: registerGObjectType,
- writable: false,
- configurable: false,
- enumerable: false,
- });
+Object.defineProperty(GObject.Object, _registerType, {
+ value: registerGObjectType,
+ writable: false,
+ configurable: false,
+ enumerable: false,
+});
- function interfaceInstanceOf(instance) {
- if (instance && typeof instance === 'object' &&
+function interfaceInstanceOf(instance) {
+ if (instance && typeof instance === 'object' &&
GObject.Interface.prototype.isPrototypeOf(this.prototype))
- return GObject.type_is_a(instance, this);
+ return GObject.type_is_a(instance, this);
- return false;
- }
+ return false;
+}
- function registerInterfaceType() {
- let klass = this;
+function registerInterfaceType() {
+ let klass = this;
- let gtypename = _createGTypeName(klass);
- let gobjectInterfaces = klass.hasOwnProperty(requires) ? klass[requires] : [];
- let props = _propertiesAsArray(klass);
- let gobjectSignals = klass.hasOwnProperty(signals) ? klass[signals] : [];
+ let gtypename = _createGTypeName(klass);
+ let gobjectInterfaces = klass.hasOwnProperty(requires) ? klass[requires] : [];
+ let props = _propertiesAsArray(klass);
+ let gobjectSignals = klass.hasOwnProperty(signals) ? klass[signals] : [];
- const [giPrototype, registeredType] = Gi.register_interface_with_class(klass, gtypename, gobjectInterfaces,
- props);
+ const [giPrototype, registeredType] = Gi.register_interface_with_class(klass, gtypename, gobjectInterfaces,
+ props);
- _defineGType(klass, giPrototype, registeredType);
- _createSignals(klass.$gtype, gobjectSignals);
+ _defineGType(klass, giPrototype, registeredType);
+ _createSignals(klass.$gtype, gobjectSignals);
- Object.defineProperty(klass, Symbol.hasInstance, {
- value: interfaceInstanceOf,
- });
+ Object.defineProperty(klass, Symbol.hasInstance, {
+ value: interfaceInstanceOf,
+ });
- return klass;
- }
+ return klass;
+}
- Object.defineProperty(GObject.Interface, _registerType, {
- value: registerInterfaceType,
- writable: false,
- configurable: false,
- enumerable: false,
- });
+Object.defineProperty(GObject.Interface, _registerType, {
+ value: registerInterfaceType,
+ writable: false,
+ configurable: false,
+ enumerable: false,
+});
- GObject.Interface._classInit = function (klass) {
- if (_registerType in klass)
- klass[_registerType]();
- else
- _resolveLegacyClassFunction(klass, _registerType).call(klass);
+GObject.Interface._classInit = function (klass) {
+ if (_registerType in klass)
+ klass[_registerType]();
+ else
+ _resolveLegacyClassFunction(klass, _registerType).call(klass);
- Object.getOwnPropertyNames(klass.prototype)
+ Object.getOwnPropertyNames(klass.prototype)
.filter(key => key !== 'constructor')
.concat(Object.getOwnPropertySymbols(klass.prototype))
.forEach(key => {
@@ -651,235 +648,234 @@ function _init() {
Object.defineProperty(klass.prototype, key, descr);
});
- return klass;
- };
-
- /**
- * Use this to signify a function that must be overridden in an
- * implementation of the interface.
- */
- GObject.NotImplementedError = class NotImplementedError extends Error {
- get name() {
- return 'NotImplementedError';
- }
- };
-
- // These will be copied in the Gtk overrides
- // Use __X__ syntax to indicate these variables should not be used publicly.
-
- GObject.__gtkCssName__ = _gtkCssName;
- GObject.__gtkTemplate__ = _gtkTemplate;
- GObject.__gtkChildren__ = _gtkChildren;
- GObject.__gtkInternalChildren__ = _gtkInternalChildren;
-
- // Expose GObject static properties for ES6 classes
-
- GObject.GTypeName = GTypeName;
- GObject.requires = requires;
- GObject.interfaces = interfaces;
- GObject.properties = properties;
- GObject.signals = signals;
-
- // Replacement for non-introspectable g_object_set()
- GObject.Object.prototype.set = function (params) {
- Object.assign(this, params);
- };
-
- GObject.Object.prototype.bind_property_full = function (...args) {
- return GjsPrivate.g_object_bind_property_full(this, ...args);
- };
-
- // fake enum for signal accumulators, keep in sync with gi/object.c
- GObject.AccumulatorType = {
- NONE: 0,
- FIRST_WINS: 1,
- TRUE_HANDLED: 2,
- };
-
- GObject.Object.prototype.disconnect = function (id) {
- return GObject.signal_handler_disconnect(this, id);
- };
- GObject.Object.prototype.block_signal_handler = function (id) {
- return GObject.signal_handler_block(this, id);
- };
- GObject.Object.prototype.unblock_signal_handler = function (id) {
- return GObject.signal_handler_unblock(this, id);
- };
- GObject.Object.prototype.stop_emission_by_name = function (detailedName) {
- return GObject.signal_stop_emission_by_name(this, detailedName);
- };
-
- // A simple workaround if you have a class with .connect, .disconnect or .emit
- // methods (such as Gio.Socket.connect or NMClient.Device.disconnect)
- // The original g_signal_* functions are not introspectable anyway, because
- // we need our own handling of signal argument marshalling
- GObject.signal_connect = function (object, name, handler) {
- return GObject.Object.prototype.connect.call(object, name, handler);
- };
- GObject.signal_connect_after = function (object, name, handler) {
- return GObject.Object.prototype.connect_after.call(object, name, handler);
- };
- GObject.signal_emit_by_name = function (object, ...nameAndArgs) {
- return GObject.Object.prototype.emit.apply(object, nameAndArgs);
- };
-
- // Replacements for signal_handler_find() and similar functions, which can't
- // work normally since we connect private closures
- GObject._real_signal_handler_find = GObject.signal_handler_find;
- GObject._real_signal_handlers_block_matched = GObject.signal_handlers_block_matched;
- GObject._real_signal_handlers_unblock_matched = GObject.signal_handlers_unblock_matched;
- GObject._real_signal_handlers_disconnect_matched = GObject.signal_handlers_disconnect_matched;
-
- /**
- * Finds the first signal handler that matches certain selection criteria.
- * The criteria are passed as properties of a match object.
- * The match object has to be non-empty for successful matches.
- * If no handler was found, a falsy value is returned.
- *
- * @function
- * @param {GObject.Object} instance - the instance owning the signal handler
- * to be found.
- * @param {object} match - a properties object indicating whether to match
- * by signal ID, detail, or callback function.
- * @param {string} [match.signalId] - signal the handler has to be connected
- * to.
- * @param {string} [match.detail] - signal detail the handler has to be
- * connected to.
- * @param {Function} [match.func] - the callback function the handler will
- * invoke.
- * @returns {number | bigint | object | null} A valid non-0 signal handler ID for
- * a successful match.
- */
- GObject.signal_handler_find = function (instance, match) {
- // For backwards compatibility
- if (arguments.length === 7)
- // eslint-disable-next-line prefer-rest-params
- return GObject._real_signal_handler_find(...arguments);
- return instance[Gi.signal_find_symbol](match);
- };
- /**
- * Blocks all handlers on an instance that match certain selection criteria.
- * The criteria are passed as properties of a match object.
- * The match object has to have at least `func` for successful matches.
- * If no handlers were found, 0 is returned, the number of blocked handlers
- * otherwise.
- *
- * @function
- * @param {GObject.Object} instance - the instance owning the signal handler
- * to be found.
- * @param {object} match - a properties object indicating whether to match
- * by signal ID, detail, or callback function.
- * @param {string} [match.signalId] - signal the handler has to be connected
- * to.
- * @param {string} [match.detail] - signal detail the handler has to be
- * connected to.
- * @param {Function} match.func - the callback function the handler will
- * invoke.
- * @returns {number} The number of handlers that matched.
- */
- GObject.signal_handlers_block_matched = function (instance, match) {
- // For backwards compatibility
- if (arguments.length === 7)
- // eslint-disable-next-line prefer-rest-params
- return GObject._real_signal_handlers_block_matched(...arguments);
- return instance[Gi.signals_block_symbol](match);
- };
- /**
- * Unblocks all handlers on an instance that match certain selection
- * criteria.
- * The criteria are passed as properties of a match object.
- * The match object has to have at least `func` for successful matches.
- * If no handlers were found, 0 is returned, the number of unblocked
- * handlers otherwise.
- * The match criteria should not apply to any handlers that are not
- * currently blocked.
- *
- * @function
- * @param {GObject.Object} instance - the instance owning the signal handler
- * to be found.
- * @param {object} match - a properties object indicating whether to match
- * by signal ID, detail, or callback function.
- * @param {string} [match.signalId] - signal the handler has to be connected
- * to.
- * @param {string} [match.detail] - signal detail the handler has to be
- * connected to.
- * @param {Function} match.func - the callback function the handler will
- * invoke.
- * @returns {number} The number of handlers that matched.
- */
- GObject.signal_handlers_unblock_matched = function (instance, match) {
- // For backwards compatibility
- if (arguments.length === 7)
- // eslint-disable-next-line prefer-rest-params
- return GObject._real_signal_handlers_unblock_matched(...arguments);
- return instance[Gi.signals_unblock_symbol](match);
- };
- /**
- * Disconnects all handlers on an instance that match certain selection
- * criteria.
- * The criteria are passed as properties of a match object.
- * The match object has to have at least `func` for successful matches.
- * If no handlers were found, 0 is returned, the number of disconnected
- * handlers otherwise.
- *
- * @function
- * @param {GObject.Object} instance - the instance owning the signal handler
- * to be found.
- * @param {object} match - a properties object indicating whether to match
- * by signal ID, detail, or callback function.
- * @param {string} [match.signalId] - signal the handler has to be connected
- * to.
- * @param {string} [match.detail] - signal detail the handler has to be
- * connected to.
- * @param {Function} match.func - the callback function the handler will
- * invoke.
- * @returns {number} The number of handlers that matched.
- */
- GObject.signal_handlers_disconnect_matched = function (instance, match) {
- // For backwards compatibility
- if (arguments.length === 7)
- // eslint-disable-next-line prefer-rest-params
- return GObject._real_signal_handlers_disconnect_matched(...arguments);
- return instance[Gi.signals_disconnect_symbol](match);
- };
-
- // Also match the macros used in C APIs, even though they're not introspected
-
- /**
- * Blocks all handlers on an instance that match `func`.
- *
- * @function
- * @param {GObject.Object} instance - the instance to block handlers from.
- * @param {Function} func - the callback function the handler will invoke.
- * @returns {number} The number of handlers that matched.
- */
- GObject.signal_handlers_block_by_func = function (instance, func) {
- return instance[Gi.signals_block_symbol]({func});
- };
- /**
- * Unblocks all handlers on an instance that match `func`.
- *
- * @function
- * @param {GObject.Object} instance - the instance to unblock handlers from.
- * @param {Function} func - the callback function the handler will invoke.
- * @returns {number} The number of handlers that matched.
- */
- GObject.signal_handlers_unblock_by_func = function (instance, func) {
- return instance[Gi.signals_unblock_symbol]({func});
- };
- /**
- * Disconnects all handlers on an instance that match `func`.
- *
- * @function
- * @param {GObject.Object} instance - the instance to remove handlers from.
- * @param {Function} func - the callback function the handler will invoke.
- * @returns {number} The number of handlers that matched.
- */
- GObject.signal_handlers_disconnect_by_func = function (instance, func) {
- return instance[Gi.signals_disconnect_symbol]({func});
- };
- GObject.signal_handlers_disconnect_by_data = function () {
- throw new Error('GObject.signal_handlers_disconnect_by_data() is not \
+ return klass;
+};
+
+/**
+ * Use this to signify a function that must be overridden in an
+ * implementation of the interface.
+ */
+GObject.NotImplementedError = class NotImplementedError extends Error {
+ get name() {
+ return 'NotImplementedError';
+ }
+};
+
+// These will be copied in the Gtk overrides
+// Use __X__ syntax to indicate these variables should not be used publicly.
+
+GObject.__gtkCssName__ = _gtkCssName;
+GObject.__gtkTemplate__ = _gtkTemplate;
+GObject.__gtkChildren__ = _gtkChildren;
+GObject.__gtkInternalChildren__ = _gtkInternalChildren;
+
+// Expose GObject static properties for ES6 classes
+
+GObject.GTypeName = GTypeName;
+GObject.requires = requires;
+GObject.interfaces = interfaces;
+GObject.properties = properties;
+GObject.signals = signals;
+
+// Replacement for non-introspectable g_object_set()
+GObject.Object.prototype.set = function (params) {
+ Object.assign(this, params);
+};
+
+GObject.Object.prototype.bind_property_full = function (...args) {
+ return GjsPrivate.g_object_bind_property_full(this, ...args);
+};
+
+// fake enum for signal accumulators, keep in sync with gi/object.c
+GObject.AccumulatorType = {
+ NONE: 0,
+ FIRST_WINS: 1,
+ TRUE_HANDLED: 2,
+};
+
+GObject.Object.prototype.disconnect = function (id) {
+ return GObject.signal_handler_disconnect(this, id);
+};
+GObject.Object.prototype.block_signal_handler = function (id) {
+ return GObject.signal_handler_block(this, id);
+};
+GObject.Object.prototype.unblock_signal_handler = function (id) {
+ return GObject.signal_handler_unblock(this, id);
+};
+GObject.Object.prototype.stop_emission_by_name = function (detailedName) {
+ return GObject.signal_stop_emission_by_name(this, detailedName);
+};
+
+// A simple workaround if you have a class with .connect, .disconnect or .emit
+// methods (such as Gio.Socket.connect or NMClient.Device.disconnect)
+// The original g_signal_* functions are not introspectable anyway, because
+// we need our own handling of signal argument marshalling
+GObject.signal_connect = function (object, name, handler) {
+ return GObject.Object.prototype.connect.call(object, name, handler);
+};
+GObject.signal_connect_after = function (object, name, handler) {
+ return GObject.Object.prototype.connect_after.call(object, name, handler);
+};
+GObject.signal_emit_by_name = function (object, ...nameAndArgs) {
+ return GObject.Object.prototype.emit.apply(object, nameAndArgs);
+};
+
+// Replacements for signal_handler_find() and similar functions, which can't
+// work normally since we connect private closures
+GObject._real_signal_handler_find = GObject.signal_handler_find;
+GObject._real_signal_handlers_block_matched = GObject.signal_handlers_block_matched;
+GObject._real_signal_handlers_unblock_matched = GObject.signal_handlers_unblock_matched;
+GObject._real_signal_handlers_disconnect_matched = GObject.signal_handlers_disconnect_matched;
+
+/**
+ * Finds the first signal handler that matches certain selection criteria.
+ * The criteria are passed as properties of a match object.
+ * The match object has to be non-empty for successful matches.
+ * If no handler was found, a falsy value is returned.
+ *
+ * @function
+ * @param {GObject.Object} instance - the instance owning the signal handler
+ * to be found.
+ * @param {object} match - a properties object indicating whether to match
+ * by signal ID, detail, or callback function.
+ * @param {string} [match.signalId] - signal the handler has to be connected
+ * to.
+ * @param {string} [match.detail] - signal detail the handler has to be
+ * connected to.
+ * @param {Function} [match.func] - the callback function the handler will
+ * invoke.
+ * @returns {number | bigint | object | null} A valid non-0 signal handler ID for
+ * a successful match.
+ */
+GObject.signal_handler_find = function (instance, match) {
+ // For backwards compatibility
+ if (arguments.length === 7)
+ // eslint-disable-next-line prefer-rest-params
+ return GObject._real_signal_handler_find(...arguments);
+ return instance[Gi.signal_find_symbol](match);
+};
+/**
+ * Blocks all handlers on an instance that match certain selection criteria.
+ * The criteria are passed as properties of a match object.
+ * The match object has to have at least `func` for successful matches.
+ * If no handlers were found, 0 is returned, the number of blocked handlers
+ * otherwise.
+ *
+ * @function
+ * @param {GObject.Object} instance - the instance owning the signal handler
+ * to be found.
+ * @param {object} match - a properties object indicating whether to match
+ * by signal ID, detail, or callback function.
+ * @param {string} [match.signalId] - signal the handler has to be connected
+ * to.
+ * @param {string} [match.detail] - signal detail the handler has to be
+ * connected to.
+ * @param {Function} match.func - the callback function the handler will
+ * invoke.
+ * @returns {number} The number of handlers that matched.
+ */
+GObject.signal_handlers_block_matched = function (instance, match) {
+ // For backwards compatibility
+ if (arguments.length === 7)
+ // eslint-disable-next-line prefer-rest-params
+ return GObject._real_signal_handlers_block_matched(...arguments);
+ return instance[Gi.signals_block_symbol](match);
+};
+/**
+ * Unblocks all handlers on an instance that match certain selection
+ * criteria.
+ * The criteria are passed as properties of a match object.
+ * The match object has to have at least `func` for successful matches.
+ * If no handlers were found, 0 is returned, the number of unblocked
+ * handlers otherwise.
+ * The match criteria should not apply to any handlers that are not
+ * currently blocked.
+ *
+ * @function
+ * @param {GObject.Object} instance - the instance owning the signal handler
+ * to be found.
+ * @param {object} match - a properties object indicating whether to match
+ * by signal ID, detail, or callback function.
+ * @param {string} [match.signalId] - signal the handler has to be connected
+ * to.
+ * @param {string} [match.detail] - signal detail the handler has to be
+ * connected to.
+ * @param {Function} match.func - the callback function the handler will
+ * invoke.
+ * @returns {number} The number of handlers that matched.
+ */
+GObject.signal_handlers_unblock_matched = function (instance, match) {
+ // For backwards compatibility
+ if (arguments.length === 7)
+ // eslint-disable-next-line prefer-rest-params
+ return GObject._real_signal_handlers_unblock_matched(...arguments);
+ return instance[Gi.signals_unblock_symbol](match);
+};
+/**
+ * Disconnects all handlers on an instance that match certain selection
+ * criteria.
+ * The criteria are passed as properties of a match object.
+ * The match object has to have at least `func` for successful matches.
+ * If no handlers were found, 0 is returned, the number of disconnected
+ * handlers otherwise.
+ *
+ * @function
+ * @param {GObject.Object} instance - the instance owning the signal handler
+ * to be found.
+ * @param {object} match - a properties object indicating whether to match
+ * by signal ID, detail, or callback function.
+ * @param {string} [match.signalId] - signal the handler has to be connected
+ * to.
+ * @param {string} [match.detail] - signal detail the handler has to be
+ * connected to.
+ * @param {Function} match.func - the callback function the handler will
+ * invoke.
+ * @returns {number} The number of handlers that matched.
+ */
+GObject.signal_handlers_disconnect_matched = function (instance, match) {
+ // For backwards compatibility
+ if (arguments.length === 7)
+ // eslint-disable-next-line prefer-rest-params
+ return GObject._real_signal_handlers_disconnect_matched(...arguments);
+ return instance[Gi.signals_disconnect_symbol](match);
+};
+
+// Also match the macros used in C APIs, even though they're not introspected
+
+/**
+ * Blocks all handlers on an instance that match `func`.
+ *
+ * @function
+ * @param {GObject.Object} instance - the instance to block handlers from.
+ * @param {Function} func - the callback function the handler will invoke.
+ * @returns {number} The number of handlers that matched.
+ */
+GObject.signal_handlers_block_by_func = function (instance, func) {
+ return instance[Gi.signals_block_symbol]({func});
+};
+/**
+ * Unblocks all handlers on an instance that match `func`.
+ *
+ * @function
+ * @param {GObject.Object} instance - the instance to unblock handlers from.
+ * @param {Function} func - the callback function the handler will invoke.
+ * @returns {number} The number of handlers that matched.
+ */
+GObject.signal_handlers_unblock_by_func = function (instance, func) {
+ return instance[Gi.signals_unblock_symbol]({func});
+};
+/**
+ * Disconnects all handlers on an instance that match `func`.
+ *
+ * @function
+ * @param {GObject.Object} instance - the instance to remove handlers from.
+ * @param {Function} func - the callback function the handler will invoke.
+ * @returns {number} The number of handlers that matched.
+ */
+GObject.signal_handlers_disconnect_by_func = function (instance, func) {
+ return instance[Gi.signals_disconnect_symbol]({func});
+};
+GObject.signal_handlers_disconnect_by_data = function () {
+ throw new Error('GObject.signal_handlers_disconnect_by_data() is not \
introspectable. Use GObject.signal_handlers_disconnect_by_func() instead.');
- };
-}
+};
diff --git a/modules/core/overrides/Gio.js b/modules/core/overrides/Gio.js
index 6cc29b17..16c5c4d9 100644
--- a/modules/core/overrides/Gio.js
+++ b/modules/core/overrides/Gio.js
@@ -1,10 +1,8 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2011 Giovanni Campagna
-var GLib = imports.gi.GLib;
-var GjsPrivate = imports.gi.GjsPrivate;
-var Signals = imports.signals;
-var Gio;
+const {GLib, Gio, GjsPrivate} = imports.gi;
+const Signals = imports.signals;
// Ensures that a Gio.UnixFDList being passed into or out of a DBus method with
// a parameter type that includes 'h' somewhere, actually has entries in it for
@@ -453,186 +451,183 @@ function _promisify(proto, asyncFunc,
};
}
-function _init() {
- Gio = this;
-
- Gio.DBus = {
- get session() {
- return Gio.bus_get_sync(Gio.BusType.SESSION, null);
- },
- get system() {
- return Gio.bus_get_sync(Gio.BusType.SYSTEM, null);
- },
-
- // Namespace some functions
- get: Gio.bus_get,
- get_finish: Gio.bus_get_finish,
- get_sync: Gio.bus_get_sync,
-
- own_name: Gio.bus_own_name,
- own_name_on_connection: Gio.bus_own_name_on_connection,
- unown_name: Gio.bus_unown_name,
-
- watch_name: Gio.bus_watch_name,
- watch_name_on_connection: Gio.bus_watch_name_on_connection,
- unwatch_name: Gio.bus_unwatch_name,
+Gio.DBus = {
+ get session() {
+ return Gio.bus_get_sync(Gio.BusType.SESSION, null);
+ },
+ get system() {
+ return Gio.bus_get_sync(Gio.BusType.SYSTEM, null);
+ },
+
+ // Namespace some functions
+ get: Gio.bus_get,
+ get_finish: Gio.bus_get_finish,
+ get_sync: Gio.bus_get_sync,
+
+ own_name: Gio.bus_own_name,
+ own_name_on_connection: Gio.bus_own_name_on_connection,
+ unown_name: Gio.bus_unown_name,
+
+ watch_name: Gio.bus_watch_name,
+ watch_name_on_connection: Gio.bus_watch_name_on_connection,
+ unwatch_name: Gio.bus_unwatch_name,
+};
+
+Gio.DBusConnection.prototype.watch_name = function (name, flags, appeared, vanished) {
+ return Gio.bus_watch_name_on_connection(this, name, flags, appeared, vanished);
+};
+Gio.DBusConnection.prototype.unwatch_name = function (id) {
+ return Gio.bus_unwatch_name(id);
+};
+Gio.DBusConnection.prototype.own_name = function (name, flags, acquired, lost) {
+ return Gio.bus_own_name_on_connection(this, name, flags, acquired, lost);
+};
+Gio.DBusConnection.prototype.unown_name = function (id) {
+ return Gio.bus_unown_name(id);
+};
+
+_injectToMethod(Gio.DBusProxy.prototype, 'init', _addDBusConvenience);
+_injectToMethod(Gio.DBusProxy.prototype, 'init_async', _addDBusConvenience);
+_injectToStaticMethod(Gio.DBusProxy, 'new_sync', _addDBusConvenience);
+_injectToStaticMethod(Gio.DBusProxy, 'new_finish', _addDBusConvenience);
+_injectToStaticMethod(Gio.DBusProxy, 'new_for_bus_sync', _addDBusConvenience);
+_injectToStaticMethod(Gio.DBusProxy, 'new_for_bus_finish', _addDBusConvenience);
+Gio.DBusProxy.prototype.connectSignal = Signals._connect;
+Gio.DBusProxy.prototype.disconnectSignal = Signals._disconnect;
+
+Gio.DBusProxy.makeProxyWrapper = _makeProxyWrapper;
+
+// Some helpers
+_wrapFunction(Gio.DBusNodeInfo, 'new_for_xml', _newNodeInfo);
+Gio.DBusInterfaceInfo.new_for_xml = _newInterfaceInfo;
+
+Gio.DBusExportedObject = GjsPrivate.DBusImplementation;
+Gio.DBusExportedObject.wrapJSObject = _wrapJSObject;
+
+// ListStore
+Gio.ListStore.prototype[Symbol.iterator] = _listModelIterator;
+Gio.ListStore.prototype.insert_sorted = function (item, compareFunc) {
+ return GjsPrivate.list_store_insert_sorted(this, item, compareFunc);
+};
+Gio.ListStore.prototype.sort = function (compareFunc) {
+ return GjsPrivate.list_store_sort(this, compareFunc);
+};
+
+// Promisify
+Gio._promisify = _promisify;
+
+// Temporary Gio.File.prototype fix
+Gio._LocalFilePrototype = Gio.File.new_for_path('/').constructor.prototype;
+
+Gio.File.prototype.replace_contents_async = function replace_contents_async(contents, etag, make_backup, flags, cancellable, callback) {
+ return this.replace_contents_bytes_async(contents, etag, make_backup, flags, cancellable, callback);
+};
+
+// Override Gio.Settings and Gio.SettingsSchema - the C API asserts if
+// trying to access a nonexistent schema or key, which is not handy for
+// shell-extension writers
+
+Gio.SettingsSchema.prototype._realGetKey = Gio.SettingsSchema.prototype.get_key;
+Gio.SettingsSchema.prototype.get_key = function (key) {
+ if (!this.has_key(key))
+ throw new Error(`GSettings key ${key} not found in schema ${this.get_id()}`);
+ return this._realGetKey(key);
+};
+
+Gio.Settings.prototype._realMethods = Object.assign({}, Gio.Settings.prototype);
+
+function createCheckedMethod(method, checkMethod = '_checkKey') {
+ return function (id, ...args) {
+ this[checkMethod](id);
+ return this._realMethods[method].call(this, id, ...args);
};
+}
- Gio.DBusConnection.prototype.watch_name = function (name, flags, appeared, vanished) {
- return Gio.bus_watch_name_on_connection(this, name, flags, appeared, vanished);
- };
- Gio.DBusConnection.prototype.unwatch_name = function (id) {
- return Gio.bus_unwatch_name(id);
- };
- Gio.DBusConnection.prototype.own_name = function (name, flags, acquired, lost) {
- return Gio.bus_own_name_on_connection(this, name, flags, acquired, lost);
- };
- Gio.DBusConnection.prototype.unown_name = function (id) {
- return Gio.bus_unown_name(id);
- };
-
- _injectToMethod(Gio.DBusProxy.prototype, 'init', _addDBusConvenience);
- _injectToMethod(Gio.DBusProxy.prototype, 'init_async', _addDBusConvenience);
- _injectToStaticMethod(Gio.DBusProxy, 'new_sync', _addDBusConvenience);
- _injectToStaticMethod(Gio.DBusProxy, 'new_finish', _addDBusConvenience);
- _injectToStaticMethod(Gio.DBusProxy, 'new_for_bus_sync', _addDBusConvenience);
- _injectToStaticMethod(Gio.DBusProxy, 'new_for_bus_finish', _addDBusConvenience);
- Gio.DBusProxy.prototype.connectSignal = Signals._connect;
- Gio.DBusProxy.prototype.disconnectSignal = Signals._disconnect;
-
- Gio.DBusProxy.makeProxyWrapper = _makeProxyWrapper;
-
- // Some helpers
- _wrapFunction(Gio.DBusNodeInfo, 'new_for_xml', _newNodeInfo);
- Gio.DBusInterfaceInfo.new_for_xml = _newInterfaceInfo;
-
- Gio.DBusExportedObject = GjsPrivate.DBusImplementation;
- Gio.DBusExportedObject.wrapJSObject = _wrapJSObject;
-
- // ListStore
- Gio.ListStore.prototype[Symbol.iterator] = _listModelIterator;
- Gio.ListStore.prototype.insert_sorted = function (item, compareFunc) {
- return GjsPrivate.list_store_insert_sorted(this, item, compareFunc);
- };
- Gio.ListStore.prototype.sort = function (compareFunc) {
- return GjsPrivate.list_store_sort(this, compareFunc);
- };
-
- // Promisify
- Gio._promisify = _promisify;
-
- // Temporary Gio.File.prototype fix
- Gio._LocalFilePrototype = Gio.File.new_for_path('/').constructor.prototype;
-
- Gio.File.prototype.replace_contents_async = function replace_contents_async(contents, etag, make_backup, flags, cancellable, callback) {
- return this.replace_contents_bytes_async(contents, etag, make_backup, flags, cancellable, callback);
- };
-
- // Override Gio.Settings and Gio.SettingsSchema - the C API asserts if
- // trying to access a nonexistent schema or key, which is not handy for
- // shell-extension writers
-
- Gio.SettingsSchema.prototype._realGetKey = Gio.SettingsSchema.prototype.get_key;
- Gio.SettingsSchema.prototype.get_key = function (key) {
- if (!this.has_key(key))
- throw new Error(`GSettings key ${key} not found in schema ${this.get_id()}`);
- return this._realGetKey(key);
- };
-
- Gio.Settings.prototype._realMethods = Object.assign({}, Gio.Settings.prototype);
-
- function createCheckedMethod(method, checkMethod = '_checkKey') {
- return function (id, ...args) {
- this[checkMethod](id);
- return this._realMethods[method].call(this, id, ...args);
- };
- }
-
- Object.assign(Gio.Settings.prototype, {
- _realInit: Gio.Settings.prototype._init, // add manually, not enumerable
- _init(props = {}) {
- // 'schema' is a deprecated alias for schema_id
- const schemaIdProp = ['schema', 'schema-id', 'schema_id',
- 'schemaId'].find(prop => prop in props);
- const settingsSchemaProp = ['settings-schema', 'settings_schema',
- 'settingsSchema'].find(prop => prop in props);
- if (!schemaIdProp && !settingsSchemaProp) {
- throw new Error('One of property \'schema-id\' or ' +
+Object.assign(Gio.Settings.prototype, {
+ _realInit: Gio.Settings.prototype._init, // add manually, not enumerable
+ _init(props = {}) {
+ // 'schema' is a deprecated alias for schema_id
+ const schemaIdProp = ['schema', 'schema-id', 'schema_id',
+ 'schemaId'].find(prop => prop in props);
+ const settingsSchemaProp = ['settings-schema', 'settings_schema',
+ 'settingsSchema'].find(prop => prop in props);
+ if (!schemaIdProp && !settingsSchemaProp) {
+ throw new Error('One of property \'schema-id\' or ' +
'\'settings-schema\' are required for Gio.Settings');
- }
+ }
- const source = Gio.SettingsSchemaSource.get_default();
- const settingsSchema = settingsSchemaProp
- ? props[settingsSchemaProp]
- : source.lookup(props[schemaIdProp], true);
+ const source = Gio.SettingsSchemaSource.get_default();
+ const settingsSchema = settingsSchemaProp
+ ? props[settingsSchemaProp]
+ : source.lookup(props[schemaIdProp], true);
- if (!settingsSchema)
- throw new Error(`GSettings schema ${props[schemaIdProp]} not found`);
+ if (!settingsSchema)
+ throw new Error(`GSettings schema ${props[schemaIdProp]} not found`);
- const settingsSchemaPath = settingsSchema.get_path();
- if (props['path'] === undefined && !settingsSchemaPath) {
- throw new Error('Attempting to create schema ' +
+ const settingsSchemaPath = settingsSchema.get_path();
+ if (props['path'] === undefined && !settingsSchemaPath) {
+ throw new Error('Attempting to create schema ' +
`'${settingsSchema.get_id()}' without a path`);
- }
+ }
- if (props['path'] !== undefined && settingsSchemaPath &&
+ if (props['path'] !== undefined && settingsSchemaPath &&
props['path'] !== settingsSchemaPath) {
- throw new Error(`GSettings created for path '${props['path']}'` +
+ throw new Error(`GSettings created for path '${props['path']}'` +
`, but schema specifies '${settingsSchemaPath}'`);
- }
+ }
+
+ return this._realInit(props);
+ },
+
+ _checkKey(key) {
+ // Avoid using has_key(); checking a JS array is faster than calling
+ // through G-I.
+ if (!this._keys)
+ this._keys = this.settings_schema.list_keys();
+
+ if (!this._keys.includes(key))
+ throw new Error(`GSettings key ${key} not found in schema ${this.schema_id}`);
+ },
+
+ _checkChild(name) {
+ if (!this._children)
+ this._children = this.list_children();
+
+ if (!this._children.includes(name))
+ throw new Error(`Child ${name} not found in GSettings schema ${this.schema_id}`);
+ },
+
+ get_boolean: createCheckedMethod('get_boolean'),
+ set_boolean: createCheckedMethod('set_boolean'),
+ get_double: createCheckedMethod('get_double'),
+ set_double: createCheckedMethod('set_double'),
+ get_enum: createCheckedMethod('get_enum'),
+ set_enum: createCheckedMethod('set_enum'),
+ get_flags: createCheckedMethod('get_flags'),
+ set_flags: createCheckedMethod('set_flags'),
+ get_int: createCheckedMethod('get_int'),
+ set_int: createCheckedMethod('set_int'),
+ get_int64: createCheckedMethod('get_int64'),
+ set_int64: createCheckedMethod('set_int64'),
+ get_string: createCheckedMethod('get_string'),
+ set_string: createCheckedMethod('set_string'),
+ get_strv: createCheckedMethod('get_strv'),
+ set_strv: createCheckedMethod('set_strv'),
+ get_uint: createCheckedMethod('get_uint'),
+ set_uint: createCheckedMethod('set_uint'),
+ get_uint64: createCheckedMethod('get_uint64'),
+ set_uint64: createCheckedMethod('set_uint64'),
+ get_value: createCheckedMethod('get_value'),
+ set_value: createCheckedMethod('set_value'),
+
+ bind: createCheckedMethod('bind'),
+ bind_writable: createCheckedMethod('bind_writable'),
+ create_action: createCheckedMethod('create_action'),
+ get_default_value: createCheckedMethod('get_default_value'),
+ get_user_value: createCheckedMethod('get_user_value'),
+ is_writable: createCheckedMethod('is_writable'),
+ reset: createCheckedMethod('reset'),
+
+ get_child: createCheckedMethod('get_child', '_checkChild'),
+});
- return this._realInit(props);
- },
-
- _checkKey(key) {
- // Avoid using has_key(); checking a JS array is faster than calling
- // through G-I.
- if (!this._keys)
- this._keys = this.settings_schema.list_keys();
-
- if (!this._keys.includes(key))
- throw new Error(`GSettings key ${key} not found in schema ${this.schema_id}`);
- },
-
- _checkChild(name) {
- if (!this._children)
- this._children = this.list_children();
-
- if (!this._children.includes(name))
- throw new Error(`Child ${name} not found in GSettings schema ${this.schema_id}`);
- },
-
- get_boolean: createCheckedMethod('get_boolean'),
- set_boolean: createCheckedMethod('set_boolean'),
- get_double: createCheckedMethod('get_double'),
- set_double: createCheckedMethod('set_double'),
- get_enum: createCheckedMethod('get_enum'),
- set_enum: createCheckedMethod('set_enum'),
- get_flags: createCheckedMethod('get_flags'),
- set_flags: createCheckedMethod('set_flags'),
- get_int: createCheckedMethod('get_int'),
- set_int: createCheckedMethod('set_int'),
- get_int64: createCheckedMethod('get_int64'),
- set_int64: createCheckedMethod('set_int64'),
- get_string: createCheckedMethod('get_string'),
- set_string: createCheckedMethod('set_string'),
- get_strv: createCheckedMethod('get_strv'),
- set_strv: createCheckedMethod('set_strv'),
- get_uint: createCheckedMethod('get_uint'),
- set_uint: createCheckedMethod('set_uint'),
- get_uint64: createCheckedMethod('get_uint64'),
- set_uint64: createCheckedMethod('set_uint64'),
- get_value: createCheckedMethod('get_value'),
- set_value: createCheckedMethod('set_value'),
-
- bind: createCheckedMethod('bind'),
- bind_writable: createCheckedMethod('bind_writable'),
- create_action: createCheckedMethod('create_action'),
- get_default_value: createCheckedMethod('get_default_value'),
- get_user_value: createCheckedMethod('get_user_value'),
- is_writable: createCheckedMethod('is_writable'),
- reset: createCheckedMethod('reset'),
-
- get_child: createCheckedMethod('get_child', '_checkChild'),
- });
-}
diff --git a/modules/core/overrides/Gtk.js b/modules/core/overrides/Gtk.js
index ce63ba4e..43a3d69e 100644
--- a/modules/core/overrides/Gtk.js
+++ b/modules/core/overrides/Gtk.js
@@ -3,162 +3,188 @@
// SPDX-FileCopyrightText: 2013 Giovanni Campagna
const Legacy = imports._legacy;
-const {Gio, GjsPrivate, GObject} = imports.gi;
+const {Gio, GjsPrivate, GObject, Gtk} = imports.gi;
const {_registerType} = imports._common;
-let Gtk;
let BuilderScope;
-function _init() {
- Gtk = this;
-
- Gtk.children = GObject.__gtkChildren__;
- Gtk.cssName = GObject.__gtkCssName__;
- Gtk.internalChildren = GObject.__gtkInternalChildren__;
- Gtk.template = GObject.__gtkTemplate__;
-
- let {GtkWidgetClass} = Legacy.defineGtkLegacyObjects(GObject, Gtk);
- Gtk.Widget.prototype.__metaclass__ = GtkWidgetClass;
-
- if (Gtk.Container && Gtk.Container.prototype.child_set_property) {
- Gtk.Container.prototype.child_set_property = function (child, property, value) {
- GjsPrivate.gtk_container_child_set_property(this, child, property, value);
- };
- }
-
- if (Gtk.CustomSorter) {
- Gtk.CustomSorter.new = GjsPrivate.gtk_custom_sorter_new;
- Gtk.CustomSorter.prototype.set_sort_func = function (sortFunc) {
- GjsPrivate.gtk_custom_sorter_set_sort_func(this, sortFunc);
- };
- }
-
- Gtk.Widget.prototype._init = function (params) {
- let wrapper = this;
-
- if (wrapper.constructor[Gtk.template]) {
- if (!BuilderScope) {
- Gtk.Widget.set_connect_func.call(wrapper.constructor,
- (builder, obj, signalName, handlerName, connectObj, flags) => {
- const swapped = flags & GObject.ConnectFlags.SWAPPED;
- const closure = _createClosure(
- builder, wrapper, handlerName, swapped, connectObj);
-
- if (flags & GObject.ConnectFlags.AFTER)
- obj.connect_after(signalName, closure);
- else
- obj.connect(signalName, closure);
- });
+if (Gtk.BuilderScope) {
+ BuilderScope = GObject.registerClass(
+ {
+ Implements: [Gtk.BuilderScope],
+ },
+ class extends GObject.Object {
+ vfunc_create_closure(builder, handlerName, flags, connectObject) {
+ const swapped = flags & Gtk.BuilderClosureFlags.SWAPPED;
+ return _createClosure(
+ builder,
+ builder.get_current_object(),
+ handlerName,
+ swapped,
+ connectObject
+ );
}
}
+ );
+}
- wrapper = GObject.Object.prototype._init.call(wrapper, params) ?? wrapper;
-
- if (wrapper.constructor[Gtk.template]) {
- let children = wrapper.constructor[Gtk.children] || [];
- for (let child of children) {
- wrapper[child.replace(/-/g, '_')] =
- wrapper.get_template_child(wrapper.constructor, child);
- }
- let internalChildren = wrapper.constructor[Gtk.internalChildren] || [];
- for (let child of internalChildren) {
- wrapper[`_${child.replace(/-/g, '_')}`] =
- wrapper.get_template_child(wrapper.constructor, child);
- }
- }
-
- return wrapper;
+Gtk.children = GObject.__gtkChildren__;
+Gtk.cssName = GObject.__gtkCssName__;
+Gtk.internalChildren = GObject.__gtkInternalChildren__;
+Gtk.template = GObject.__gtkTemplate__;
+
+let {GtkWidgetClass} = Legacy.defineGtkLegacyObjects(GObject, Gtk);
+Gtk.Widget.prototype.__metaclass__ = GtkWidgetClass;
+
+if (Gtk.Container && Gtk.Container.prototype.child_set_property) {
+ Gtk.Container.prototype.child_set_property = function (
+ child,
+ property,
+ value
+ ) {
+ GjsPrivate.gtk_container_child_set_property(
+ this,
+ child,
+ property,
+ value
+ );
};
+}
- Gtk.Widget._classInit = function (klass) {
- return GObject.Object._classInit(klass);
+if (Gtk.CustomSorter) {
+ Gtk.CustomSorter.new = GjsPrivate.gtk_custom_sorter_new;
+ Gtk.CustomSorter.prototype.set_sort_func = function (sortFunc) {
+ GjsPrivate.gtk_custom_sorter_set_sort_func(this, sortFunc);
};
+}
+
+Gtk.Widget.prototype._init = function (params) {
+ let wrapper = this;
+
+ if (wrapper.constructor[Gtk.template]) {
+ if (!BuilderScope) {
+ Gtk.Widget.set_connect_func.call(
+ wrapper.constructor,
+ (builder, obj, signalName, handlerName, connectObj, flags) => {
+ const swapped = flags & GObject.ConnectFlags.SWAPPED;
+ const closure = _createClosure(
+ builder,
+ wrapper,
+ handlerName,
+ swapped,
+ connectObj
+ );
+
+ if (flags & GObject.ConnectFlags.AFTER)
+ obj.connect_after(signalName, closure);
+ else
+ obj.connect(signalName, closure);
+ }
+ );
+ }
+ }
- function registerWidgetType() {
- let klass = this;
+ wrapper = GObject.Object.prototype._init.call(wrapper, params) ?? wrapper;
- let template = klass[Gtk.template];
- let cssName = klass[Gtk.cssName];
- let children = klass[Gtk.children];
- let internalChildren = klass[Gtk.internalChildren];
+ if (wrapper.constructor[Gtk.template]) {
+ let children = wrapper.constructor[Gtk.children] || [];
+ for (let child of children) {
+ wrapper[child.replace(/-/g, '_')] = wrapper.get_template_child(
+ wrapper.constructor,
+ child
+ );
+ }
- if (template) {
- klass.prototype._instance_init = function () {
- this.init_template();
- };
+ let internalChildren = wrapper.constructor[Gtk.internalChildren] || [];
+ for (let child of internalChildren) {
+ wrapper[`_${child.replace(/-/g, '_')}`] =
+ wrapper.get_template_child(wrapper.constructor, child);
}
+ }
- GObject.Object[_registerType].call(klass);
+ return wrapper;
+};
- if (cssName)
- Gtk.Widget.set_css_name.call(klass, cssName);
+Gtk.Widget._classInit = function (klass) {
+ return GObject.Object._classInit(klass);
+};
- if (template) {
- if (typeof template === 'string') {
- if (template.startsWith('resource:///')) {
- Gtk.Widget.set_template_from_resource.call(klass,
- template.slice(11));
- } else if (template.startsWith('file:///')) {
- let file = Gio.File.new_for_uri(template);
- let [, contents] = file.load_contents(null);
- Gtk.Widget.set_template.call(klass, contents);
- }
- } else {
- Gtk.Widget.set_template.call(klass, template);
- }
+function registerWidgetType() {
+ let klass = this;
- if (BuilderScope)
- Gtk.Widget.set_template_scope.call(klass, new BuilderScope());
- }
+ let template = klass[Gtk.template];
+ let cssName = klass[Gtk.cssName];
+ let children = klass[Gtk.children];
+ let internalChildren = klass[Gtk.internalChildren];
- if (children) {
- children.forEach(child =>
- Gtk.Widget.bind_template_child_full.call(klass, child, false, 0));
- }
+ if (template) {
+ klass.prototype._instance_init = function () {
+ this.init_template();
+ };
+ }
- if (internalChildren) {
- internalChildren.forEach(child =>
- Gtk.Widget.bind_template_child_full.call(klass, child, true, 0));
+ GObject.Object[_registerType].call(klass);
+
+ if (cssName)
+ Gtk.Widget.set_css_name.call(klass, cssName);
+
+ if (template) {
+ if (typeof template === 'string') {
+ if (template.startsWith('resource:///')) {
+ Gtk.Widget.set_template_from_resource.call(
+ klass,
+ template.slice(11)
+ );
+ } else if (template.startsWith('file:///')) {
+ let file = Gio.File.new_for_uri(template);
+ let [, contents] = file.load_contents(null);
+ Gtk.Widget.set_template.call(klass, contents);
+ }
+ } else {
+ Gtk.Widget.set_template.call(klass, template);
}
+
+ if (BuilderScope)
+ Gtk.Widget.set_template_scope.call(klass, new BuilderScope());
}
- Object.defineProperty(Gtk.Widget, _registerType, {
- value: registerWidgetType,
- writable: false,
- configurable: false,
- enumerable: false,
- });
-
- if (Gtk.Widget.prototype.get_first_child) {
- Gtk.Widget.prototype[Symbol.iterator] = function* () {
- for (let c = this.get_first_child(); c; c = c.get_next_sibling())
- yield c;
- };
+ if (children) {
+ children.forEach(child =>
+ Gtk.Widget.bind_template_child_full.call(klass, child, false, 0)
+ );
}
- if (Gtk.BuilderScope) {
- BuilderScope = GObject.registerClass({
- Implements: [Gtk.BuilderScope],
- }, class extends GObject.Object {
- vfunc_create_closure(builder, handlerName, flags, connectObject) {
- const swapped = flags & Gtk.BuilderClosureFlags.SWAPPED;
- return _createClosure(
- builder, builder.get_current_object(),
- handlerName, swapped, connectObject);
- }
- });
+ if (internalChildren) {
+ internalChildren.forEach(child =>
+ Gtk.Widget.bind_template_child_full.call(klass, child, true, 0)
+ );
}
}
+Object.defineProperty(Gtk.Widget, _registerType, {
+ value: registerWidgetType,
+ writable: false,
+ configurable: false,
+ enumerable: false,
+});
+
+if (Gtk.Widget.prototype.get_first_child) {
+ Gtk.Widget.prototype[Symbol.iterator] = function* () {
+ for (let c = this.get_first_child(); c; c = c.get_next_sibling())
+ yield c;
+ };
+}
+
function _createClosure(builder, thisArg, handlerName, swapped, connectObject) {
connectObject = connectObject || thisArg;
if (swapped) {
throw new Error('Unsupported template signal flag "swapped"');
} else if (typeof thisArg[handlerName] === 'undefined') {
- throw new Error(`A handler called ${handlerName} was not ` +
- `defined on ${thisArg}`);
+ throw new Error(
+ `A handler called ${handlerName} was not defined on ${thisArg}`
+ );
}
return thisArg[handlerName].bind(connectObject);
diff --git a/modules/core/overrides/cairo.js b/modules/core/overrides/cairo.js
index 1d3ba0f9..0718dce0 100644
--- a/modules/core/overrides/cairo.js
+++ b/modules/core/overrides/cairo.js
@@ -4,6 +4,6 @@
// This override adds the builtin Cairo bindings to imports.gi.cairo.
// (It's confusing to have two incompatible ways to import Cairo.)
-function _init() {
- Object.assign(this, imports.cairo);
-}
+const {cairo} = imports.gi;
+Object.assign(cairo, imports.cairo);
+