gjs: update to 1.68.0.

This commit is contained in:
Enno Boland 2021-04-03 12:45:32 +02:00
parent 03df84084b
commit 97fabd5921
No known key found for this signature in database
GPG key ID: 5A7B9F1D0DFEB55D
5 changed files with 388 additions and 2 deletions

View file

@ -0,0 +1,58 @@
From 1572849a875632a84bec664b2acb41fee54a72c2 Mon Sep 17 00:00:00 2001
From: Philip Chimento <philip.chimento@gmail.com>
Date: Sun, 21 Mar 2021 11:32:52 -0700
Subject: [PATCH 2/6] GObject: Don't autogenerate accessors for CONSTRUCT_ONLY
properties
Since we redefine CONSTRUCT_ONLY properties as readonly data properties
when they are set, the autogenerated accessors would be wrong.
See: #391
---
installed-tests/js/testGObjectClass.js | 7 +++++++
modules/core/_common.js | 2 ++
2 files changed, 9 insertions(+)
diff --git a/installed-tests/js/testGObjectClass.js b/installed-tests/js/testGObjectClass.js
index 4cf3a867..f0a57a84 100644
--- a/installed-tests/js/testGObjectClass.js
+++ b/installed-tests/js/testGObjectClass.js
@@ -766,6 +766,10 @@ describe('Auto accessor generation', function () {
'Long-named property', GObject.ParamFlags.READWRITE, 0, 100, 48),
'construct': GObject.ParamSpec.int('construct', 'Construct', 'Construct',
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, 0, 100, 96),
+ 'construct-only': GObject.ParamSpec.int('construct-only', 'Construct only',
+ 'Construct-only property',
+ GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
+ 0, 100, 80),
'snake-name': GObject.ParamSpec.int('snake-name', 'Snake name',
'Snake-cased property', GObject.ParamFlags.READWRITE, 0, 100, 36),
'camel-name': GObject.ParamSpec.int('camel-name', 'Camel name',
@@ -844,8 +848,11 @@ describe('Auto accessor generation', function () {
it("initial value is the param spec's default value", function () {
expect(a.simple).toEqual(24);
+ expect(a.long_long_name).toEqual(48);
+ expect(a.longLongName).toEqual(48);
expect(a['long-long-name']).toEqual(48);
expect(a.construct).toEqual(96);
+ expect(a.construct_only).toEqual(80);
});
it('notify when the property changes', function () {
diff --git a/modules/core/_common.js b/modules/core/_common.js
index 45bbefb7..edc70215 100644
--- a/modules/core/_common.js
+++ b/modules/core/_common.js
@@ -59,6 +59,8 @@ function _generateAccessors(pspec, propdesc, GObject) {
function _checkAccessors(proto, pspec, GObject) {
const {name, flags} = pspec;
+ if (flags & GObject.ParamFlags.CONSTRUCT_ONLY)
+ return;
const underscoreName = name.replace(/-/g, '_');
const camelName = name.replace(/-([a-z])/g, match => match[1].toUpperCase());
--
2.30.2

View file

@ -0,0 +1,124 @@
From c4231d5917b1a06d1e3b788322c71cfdb41a0249 Mon Sep 17 00:00:00 2001
From: Philip Chimento <philip.chimento@gmail.com>
Date: Sun, 21 Mar 2021 11:37:58 -0700
Subject: [PATCH 3/6] GObject: Define camel and kebab variants of
CONSTRUCT_ONLY properties
Since we redefine CONSTRUCT_ONLY properties to be readonly data properties
when they are set, we must also define camelCase and kebab-case variations
in order to be consistent with the other property accessors.
Closes: #391
---
gi/gobject.cpp | 11 +++++++----
gjs/jsapi-util-string.cpp | 21 +++++++++++++++++++++
gjs/jsapi-util.h | 1 +
installed-tests/js/testGObjectClass.js | 19 +++++++++++++++++++
4 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/gi/gobject.cpp b/gi/gobject.cpp
index 27c7d13c..65ed6638 100644
--- a/gi/gobject.cpp
+++ b/gi/gobject.cpp
@@ -55,10 +55,13 @@ static bool jsobj_set_gproperty(JSContext* cx, JS::HandleObject object,
GjsAutoChar underscore_name = gjs_hyphen_to_underscore(pspec->name);
- if (pspec->flags & G_PARAM_CONSTRUCT_ONLY)
- return JS_DefineProperty(
- cx, object, underscore_name, jsvalue,
- GJS_MODULE_PROP_FLAGS | JSPROP_READONLY);
+ if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) {
+ unsigned flags = GJS_MODULE_PROP_FLAGS | JSPROP_READONLY;
+ GjsAutoChar camel_name = gjs_hyphen_to_camel(pspec->name);
+ return JS_DefineProperty(cx, object, underscore_name, jsvalue, flags) &&
+ JS_DefineProperty(cx, object, camel_name, jsvalue, flags) &&
+ JS_DefineProperty(cx, object, pspec->name, jsvalue, flags);
+ }
return JS_SetProperty(cx, object, underscore_name, jsvalue);
}
diff --git a/gjs/jsapi-util-string.cpp b/gjs/jsapi-util-string.cpp
index e318b514..45f297a7 100644
--- a/gjs/jsapi-util-string.cpp
+++ b/gjs/jsapi-util-string.cpp
@@ -4,6 +4,7 @@
#include <config.h>
+#include <ctype.h> // for toupper
#include <stdint.h>
#include <string.h> // for size_t, strlen
#include <sys/types.h> // for ssize_t
@@ -53,6 +54,26 @@ char* gjs_hyphen_to_underscore(const char* str) {
return retval;
}
+GjsAutoChar gjs_hyphen_to_camel(const char* str) {
+ GjsAutoChar retval = static_cast<char*>(g_malloc(strlen(str) + 1));
+ const char* input_iter = str;
+ char* output_iter = retval.get();
+ bool uppercase_next = false;
+ while (*input_iter != '\0') {
+ if (*input_iter == '-') {
+ uppercase_next = true;
+ } else if (uppercase_next) {
+ *output_iter++ = toupper(*input_iter);
+ uppercase_next = false;
+ } else {
+ *output_iter++ = *input_iter;
+ }
+ input_iter++;
+ }
+ *output_iter = '\0';
+ return retval;
+}
+
/**
* gjs_string_to_utf8:
* @cx: JSContext
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 11c23776..a6b66261 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -542,6 +542,7 @@ bool gjs_object_require_converted_property(JSContext *context,
[[nodiscard]] std::string gjs_debug_id(jsid id);
[[nodiscard]] char* gjs_hyphen_to_underscore(const char* str);
+[[nodiscard]] GjsAutoChar gjs_hyphen_to_camel(const char* str);
#if defined(G_OS_WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1900))
[[nodiscard]] std::wstring gjs_win32_vc140_utf8_to_utf16(const char* str);
diff --git a/installed-tests/js/testGObjectClass.js b/installed-tests/js/testGObjectClass.js
index f0a57a84..7073ccba 100644
--- a/installed-tests/js/testGObjectClass.js
+++ b/installed-tests/js/testGObjectClass.js
@@ -853,6 +853,25 @@ describe('Auto accessor generation', function () {
expect(a['long-long-name']).toEqual(48);
expect(a.construct).toEqual(96);
expect(a.construct_only).toEqual(80);
+ expect(a.constructOnly).toEqual(80);
+ expect(a['construct-only']).toEqual(80);
+ });
+
+ it('set properties at construct time', function () {
+ a = new AutoAccessors({
+ simple: 1,
+ longLongName: 1,
+ construct: 1,
+ 'construct-only': 1,
+ });
+ expect(a.simple).toEqual(1);
+ expect(a.long_long_name).toEqual(1);
+ expect(a.longLongName).toEqual(1);
+ expect(a['long-long-name']).toEqual(1);
+ expect(a.construct).toEqual(1);
+ expect(a.construct_only).toEqual(1);
+ expect(a.constructOnly).toEqual(1);
+ expect(a['construct-only']).toEqual(1);
});
it('notify when the property changes', function () {
--
2.30.2

View file

@ -0,0 +1,27 @@
From ec9385b89cb2bce0615093c3c957cbbb5ea6b769 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 24 Mar 2021 23:30:19 +0100
Subject: [PATCH 4/6] overrides/Gio: Fix _LocalFilePrototype
Recent GIO versions return a GDummyFile for '', which isn't the prototype
people are expecting to promisify when using _LocalFilePrototype.
---
modules/core/overrides/Gio.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/core/overrides/Gio.js b/modules/core/overrides/Gio.js
index 10872efb..d51738e0 100644
--- a/modules/core/overrides/Gio.js
+++ b/modules/core/overrides/Gio.js
@@ -495,7 +495,7 @@ function _init() {
Gio._promisify = _promisify;
// Temporary Gio.File.prototype fix
- Gio._LocalFilePrototype = Gio.File.new_for_path('').constructor.prototype;
+ Gio._LocalFilePrototype = Gio.File.new_for_path('/').constructor.prototype;
// Override Gio.Settings and Gio.SettingsSchema - the C API asserts if
// trying to access a nonexistent schema or key, which is not handy for
--
2.30.2

View file

@ -0,0 +1,176 @@
From 78bfccd3125d54caf8e1c0b8d2b84643e717a8b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Wed, 24 Mar 2021 18:06:06 +0100
Subject: [PATCH 6/6] object: Return undefined and not the actual function on
disposed objects
When calling a proto function on a disposed object we return true not to
throw, however when doing this we implicitly return to JS the actual
underlying function pointer and that may cause use the return value to
be used to wrongly set a variable or to be wrongly evaluated.
To avoid this and be consistent, return undefined instead.
Adapt tests for this and add more for uncovered methods.
Fixes #396
---
gi/object.cpp | 17 ++++++--
.../js/testGObjectDestructionAccess.js | 41 ++++++++++++++++---
2 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/gi/object.cpp b/gi/object.cpp
index 598e6bb0..39ce7f5f 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -327,8 +327,10 @@ bool ObjectBase::prop_getter(JSContext* cx, unsigned argc, JS::Value* vp) {
bool ObjectInstance::prop_getter_impl(JSContext* cx, JS::HandleString name,
JS::MutableHandleValue rval) {
- if (!check_gobject_disposed("get any property from"))
+ if (!check_gobject_disposed("get any property from")) {
+ rval.setUndefined();
return true;
+ }
GValue gvalue = { 0, };
@@ -1877,8 +1879,10 @@ ObjectInstance::connect_impl(JSContext *context,
gjs_debug_gsignal("connect obj %p priv %p", m_wrapper.get(), this);
- if (!check_gobject_disposed("connect to any signal on"))
+ if (!check_gobject_disposed("connect to any signal on")) {
+ args.rval().setInt32(0);
return true;
+ }
JS::UniqueChars signal_name;
JS::RootedObject callback(context);
@@ -1940,8 +1944,10 @@ ObjectInstance::emit_impl(JSContext *context,
gjs_debug_gsignal("emit obj %p priv %p argc %d", m_wrapper.get(), this,
argv.length());
- if (!check_gobject_disposed("emit any signal on"))
+ if (!check_gobject_disposed("emit any signal on")) {
+ argv.rval().setUndefined();
return true;
+ }
JS::UniqueChars signal_name;
if (!gjs_parse_call_args(context, "emit", argv, "!s",
@@ -2104,8 +2110,10 @@ bool ObjectInstance::signal_find_impl(JSContext* cx, const JS::CallArgs& args) {
gjs_debug_gsignal("[Gi.signal_find_symbol]() obj %p priv %p argc %d",
m_wrapper.get(), this, args.length());
- if (!check_gobject_disposed("find any signal on"))
+ if (!check_gobject_disposed("find any signal on")) {
+ args.rval().setInt32(0);
return true;
+ }
JS::RootedObject match(cx);
if (!gjs_parse_call_args(cx, "[Gi.signal_find_symbol]", args, "o", "match",
@@ -2179,6 +2187,7 @@ bool ObjectInstance::signals_action_impl(JSContext* cx,
m_wrapper.get(), this, args.length());
if (!check_gobject_disposed((action_name + " any signal on").c_str())) {
+ args.rval().setInt32(0);
return true;
}
JS::RootedObject match(cx);
diff --git a/installed-tests/js/testGObjectDestructionAccess.js b/installed-tests/js/testGObjectDestructionAccess.js
index ed1d6bb6..0b35d859 100644
--- a/installed-tests/js/testGObjectDestructionAccess.js
+++ b/installed-tests/js/testGObjectDestructionAccess.js
@@ -5,6 +5,7 @@
imports.gi.versions.Gtk = '3.0';
const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
describe('Access to destroyed GObject', function () {
@@ -23,7 +24,7 @@ describe('Access to destroyed GObject', function () {
GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_CRITICAL,
'Object Gtk.Window (0x*');
- void destroyedWindow.title;
+ expect(destroyedWindow.title).toBeUndefined();
GLib.test_assert_expected_messages_internal('Gjs', 'testGObjectDestructionAccess.js', 0,
'testExceptionInDestroyedObjectPropertyGet');
@@ -45,7 +46,7 @@ describe('Access to destroyed GObject', function () {
GLib.test_expect_message('Gtk', GLib.LogLevelFlags.LEVEL_CRITICAL,
'*GTK_IS_WINDOW*');
- void destroyedWindow.get_title();
+ expect(destroyedWindow.get_title()).toBeNull();
GLib.test_assert_expected_messages_internal('Gjs', 'testGObjectDestructionAccess.js', 0,
'testExceptionInDestroyedObjectMethodGet');
@@ -67,7 +68,7 @@ describe('Access to destroyed GObject', function () {
GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_CRITICAL,
'Object Gtk.Window (0x*');
- destroyedWindow.connect('foo-signal', () => {});
+ expect(destroyedWindow.connect('foo-signal', () => {})).toBe(0);
GLib.test_assert_expected_messages_internal('Gjs', 'testGObjectDestructionAccess.js', 0,
'testExceptionInDestroyedObjectConnect');
@@ -77,7 +78,7 @@ describe('Access to destroyed GObject', function () {
GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_CRITICAL,
'Object Gtk.Window (0x*');
- destroyedWindow.connect_after('foo-signal', () => {});
+ expect(destroyedWindow.connect_after('foo-signal', () => {})).toBe(0);
GLib.test_assert_expected_messages_internal('Gjs', 'testGObjectDestructionAccess.js', 0,
'testExceptionInDestroyedObjectConnectAfter');
@@ -87,12 +88,42 @@ describe('Access to destroyed GObject', function () {
GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_CRITICAL,
'Object Gtk.Window (0x*');
- destroyedWindow.emit('foo-signal');
+ expect(destroyedWindow.emit('foo-signal')).toBeUndefined();
GLib.test_assert_expected_messages_internal('Gjs', 'testGObjectDestructionAccess.js', 0,
'testExceptionInDestroyedObjectEmit');
});
+ it('Proto function signals_disconnect', function () {
+ GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_CRITICAL,
+ 'Object Gtk.Window (0x*');
+
+ expect(GObject.signal_handlers_disconnect_by_func(destroyedWindow, () => {})).toBe(0);
+
+ GLib.test_assert_expected_messages_internal('Gjs', 'testGObjectDestructionAccess.js', 0,
+ 'testExceptionInDestroyedObjectSignalsDisconnect');
+ });
+
+ it('Proto function signals_block', function () {
+ GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_CRITICAL,
+ 'Object Gtk.Window (0x*');
+
+ expect(GObject.signal_handlers_block_by_func(destroyedWindow, () => {})).toBe(0);
+
+ GLib.test_assert_expected_messages_internal('Gjs', 'testGObjectDestructionAccess.js', 0,
+ 'testExceptionInDestroyedObjectSignalsBlock');
+ });
+
+ it('Proto function signals_unblock', function () {
+ GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_CRITICAL,
+ 'Object Gtk.Window (0x*');
+
+ expect(GObject.signal_handlers_unblock_by_func(destroyedWindow, () => {})).toBe(0);
+
+ GLib.test_assert_expected_messages_internal('Gjs', 'testGObjectDestructionAccess.js', 0,
+ 'testExceptionInDestroyedObjectSignalsUnblock');
+ });
+
it('Proto function toString', function () {
expect(destroyedWindow.toString()).toMatch(
/\[object \(FINALIZED\) instance wrapper GIName:Gtk.Window jsobj@0x[a-f0-9]+ native@0x[a-f0-9]+\]/);
--
2.30.2

View file

@ -1,6 +1,6 @@
# Template file for 'gjs'
pkgname=gjs
version=1.66.0
version=1.68.0
revision=1
build_style=meson
build_helper="gir qemu"
@ -14,7 +14,8 @@ license="MIT, LGPL-2.0-or-later"
homepage="https://wiki.gnome.org/action/show/Projects/Gjs"
changelog="https://gitlab.gnome.org/GNOME/gjs/blob/gnome-3-30/NEWS"
distfiles="${GNOME_SITE}/${pkgname}/${version%.*}/${pkgname}-${version}.tar.xz"
checksum=f30cf90e016db6c8fdd0059749559611760f0721f375b2b61e0b7239b43ab5f8
checksum=f00e74a00e81ab61bb92669e0f1c8bb613cc019586097f06aed0572efcaf1aef
patch_args="-Np1"
post_install() {
vlicense COPYING