gjs issueshttps://gitlab.gnome.org/GNOME/gjs/-/issues2024-03-14T04:44:04Zhttps://gitlab.gnome.org/GNOME/gjs/-/issues/607Cannot throw JS errors across FFI boundary2024-03-14T04:44:04ZPhilip ChimentoCannot throw JS errors across FFI boundaryThe following program demonstrates how you can throw an exception that can't be caught:
```js
import System from 'system';
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=4.0';
const App = GObject.registerClass(cla...The following program demonstrates how you can throw an exception that can't be caught:
```js
import System from 'system';
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=4.0';
const App = GObject.registerClass(class extends Gtk.Application {
vfunc_activate() {
super.vfunc_activate();
const win = new Gtk.ApplicationWindow({application: this});
win.connect('close-request', () => {
this.quit();
throw 'No catch, only log';
});
win.present();
}
});
const app = new App({applicationId: 'app.test'});
try {
app.run([System.programInvocationName, ...System.programArgs]);
} catch (e) {
print('catch');
}
```
The `close-request` signal handler doesn't have a `GError**` parameter in C, so there's nowhere to throw the JS value to. It is just logged instead. The `try` block at the bottom of the program doesn't do anything.
It _should_ be possible to implement this such that exceptions thrown into an FFI boundary are stored and re-thrown when control returns back to JS at a higher level. But when exactly? In this case, we'd want the exception to be re-thrown when the main loop exits, at the end of `Application.run`. But that's definitely not always the case. Here's a similar program that throws an exception in a button clicked handler:
```js
import System from 'system';
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=4.0';
const App = GObject.registerClass(class extends Gtk.Application {
vfunc_activate() {
super.vfunc_activate();
const win = new Gtk.ApplicationWindow({application: this});
win.connect('close-request', () => {
this.quit();
});
const button = new Gtk.Button({label: 'Throw'});
button.connect('clicked', () => {
throw 'No catch, only log';
});
win.set_child(button);
win.present();
}
});
const app = new App({applicationId: 'app.test'});
try {
app.run([System.programInvocationName, ...System.programArgs]);
} catch (e) {
print('catch');
}
```
Would we want to stop the main loop if an exception was thrown in a signal handler? That seems like the right thing to do in this second example. But that would potentially break a _lot_ of existing code, like actually make code that previously worked stop working.https://gitlab.gnome.org/GNOME/gjs/-/issues/606Strange warning messages in Uint8Array to guint8* marshalling2024-03-13T03:42:24ZPhilip ChimentoStrange warning messages in Uint8Array to guint8* marshallingIn the following example, the first call succeeds, while the other two log a critical (`g_output_stream_write: assertion 'buffer != NULL' failed`).
```js
import Gio from 'gi://Gio';
// Works
Gio.MemoryOutputStream.new_resizable().write(...In the following example, the first call succeeds, while the other two log a critical (`g_output_stream_write: assertion 'buffer != NULL' failed`).
```js
import Gio from 'gi://Gio';
// Works
Gio.MemoryOutputStream.new_resizable().write(new Uint8Array([0]), null)
// I can't think of a use-case, but should be valid?
Gio.MemoryOutputStream.new_resizable().write(new Uint8Array([]), null)
// Zero-length string, I think should equate to new Uint8Array([0])
Gio.MemoryOutputStream.new_resizable().write('', null)
```
It seems like if we explicitly pass a zero-length buffer in GJS, it should not translate to a null pointer in C.
The string conversion is maybe not so odd if you assume that the second call is already broken. It probably translates to a zero-length buffer, since JS strings are not zero-terminated.https://gitlab.gnome.org/GNOME/gjs/-/issues/604Make use of malloc_trim() to hand memory back to the system2024-03-12T05:56:50ZJonas DreßlerMake use of malloc_trim() to hand memory back to the systemJavaScript programs (especially long-lived ones like gnome-shell) can have high memory usage over short timeframes, where the exact amount of memory used can hardly be controlled due to JS being garbage collected. This can lead to gjs ha...JavaScript programs (especially long-lived ones like gnome-shell) can have high memory usage over short timeframes, where the exact amount of memory used can hardly be controlled due to JS being garbage collected. This can lead to gjs having to allocate lots of memory on the heap to allow for some short high-memory requirement, but then never handing that back to the system even after garbage collection.
That's because `malloc()` and `free()` are highly optimized and they silently keep allocated memory around after it's been `free()`'d, which will allow for much quicker results on subsequent calls to `malloc()`.
This unused memory can be handed back to the system by calling `malloc_trim()`.
It probably makes sense for gjs to make use of `malloc_trim()`, especially once the [Big Hammer is removed](https://gitlab.gnome.org/GNOME/gjs/-/issues/217). Right now, with GC running every 10 seconds, the heap probably won't ever grow to the point where gjs is using a significant amount of system RAM. But once GC runs less often again, and gjs temporarily (between two GC cycles) needs lots of memory, it might make sense to call `malloc_trim()` after that GC freed lots or memory (this would likely need some kind of heuristic, because over-eager calling of `malloc_trim()` also seems like a bad idea).https://gitlab.gnome.org/GNOME/gjs/-/issues/603Support flat C array return values2024-03-11T03:59:45ZPhilip ChimentoSupport flat C array return valuesFollowing up from #601.
We support flat C arrays, but only of `GValue`. Trying to call a function that returns a flat C array of any other type, throws an exception referencing this issue.
Reproducer:
```js
import GTop from 'gi://GTop'...Following up from #601.
We support flat C arrays, but only of `GValue`. Trying to call a function that returns a flat C array of any other type, throws an exception referencing this issue.
Reproducer:
```js
import GTop from 'gi://GTop';
const buf = new GTop.glibtop_mountlist();
const mountlist = GTop.glibtop_get_mountlist(buf, 0);
```
(`glibtop_get_mountlist` seems like an awkward API with the in-out buffer, though, and requires an external dependency; so any better examples of an API like this inside e.g. Gio would be appreciated)
For reference, introspection data:
```xml
<return-value transfer-ownership="full">
<array c:type="glibtop_mountentry*">
<type name="glibtop_mountentry" c:type="glibtop_mountentry"/>
</array>
</return-value>
```
Probably the best way to implement this is to take the existing special-case support for GValue flat arrays and generalize it to any struct. The complication will be that by not special-casing a struct with a size known at compile time, the size of the struct will only be known at runtime.
The code for this is in `gjs_array_from_zero_terminated_c_array()` in the `glibtop_get_mountlist` case, but will also need to be supported elsewhere.
gobject-introspection contains tests for GValue flat arrays. Check if they cover all the kinds of array (zero-terminated, fixed-length, length-parameter) as well as transfer (full, none; container doesn't seem to apply here) and check that we support in and out parameters as well as return values (inout doesn't seem to apply here.)https://gitlab.gnome.org/GNOME/gjs/-/issues/609gnome-shell process stuck and begun to consume 100% CPU when I entering comma...2024-03-21T05:07:29ZMikhail Gavrilovgnome-shell process stuck and begun to consume 100% CPU when I entering command in gnome-terminal![IMG_2852](/uploads/c93087162fee0e4963dfab6f5c26152d/IMG_2852.JPEG)
![Screenshot_2024-01-26_at_01.26.20](/uploads/e375ff5d8e8f473297bdb484745c0caa/Screenshot_2024-01-26_at_01.26.20.png)
[gnome-shell-backtrace.txt](/uploads/5acbf1242f1...![IMG_2852](/uploads/c93087162fee0e4963dfab6f5c26152d/IMG_2852.JPEG)
![Screenshot_2024-01-26_at_01.26.20](/uploads/e375ff5d8e8f473297bdb484745c0caa/Screenshot_2024-01-26_at_01.26.20.png)
[gnome-shell-backtrace.txt](/uploads/5acbf1242f11d81957da33567ad89b71/gnome-shell-backtrace.txt)
```
mikhail@primary-ws ~> rpm -qa | grep gnome-shell
gnome-shell-extension-background-logo-45~beta-1.fc40.noarch
gnome-shell-extension-appindicator-57-1.fc40.noarch
gnome-shell-extension-gamemode-8-5.fc39.noarch
gnome-shell-extension-common-46~alpha-1.fc40.noarch
gnome-shell-extension-apps-menu-46~alpha-1.fc40.noarch
gnome-shell-extension-launch-new-instance-46~alpha-1.fc40.noarch
gnome-shell-extension-places-menu-46~alpha-1.fc40.noarch
gnome-shell-extension-window-list-46~alpha-1.fc40.noarch
gnome-shell-46~alpha-6.fc40.x86_64
gnome-shell-debugsource-46~alpha-6.fc40.x86_64
gnome-shell-debuginfo-46~alpha-6.fc40.x86_64
mikhail@primary-ws ~> rpm -qa | grep mutter
mutter-debugsource-46~alpha-2.fc40.x86_64
mutter-common-46~alpha-2.fc40.noarch
mutter-46~alpha-2.fc40.x86_64
mutter-debuginfo-46~alpha-2.fc40.x86_64
```
Downstream report: https://bugzilla.redhat.com/show_bug.cgi?id=2260389https://gitlab.gnome.org/GNOME/gjs/-/issues/593Facility for correctly converting POSIX locale codes into Intl locale codes2023-12-26T18:10:15ZPhilip ChimentoFacility for correctly converting POSIX locale codes into Intl locale codes# Description #
JavaScript's `Intl` APIs take a locale code such as `en-CA`, called a [BCP 47](https://datatracker.ietf.org/doc/html/rfc5646) locale code. However, the GNOME platform works with locale codes such as `en_CA`, called POSIX ...# Description #
JavaScript's `Intl` APIs take a locale code such as `en-CA`, called a [BCP 47](https://datatracker.ietf.org/doc/html/rfc5646) locale code. However, the GNOME platform works with locale codes such as `en_CA`, called POSIX locale codes, from environment variables such as `LC_ALL` and from APIs such as `GLib.get_language_names()`.
I learned [recently](https://github.com/tc39/ecma402/issues/777#issuecomment-1816614443) that it is not correct to convert from POSIX to BCP 47 simply by replacing the `_` with a `-`. This works in many cases, but the correct transformation is much more complicated.
To get the best adoption of `Intl` in GJS, we should provide this transformation in the platform somehow. This issue should discuss what form that API should take.
# Prior Art #
- Browser environments have [`navigator.language`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/language) to get the current BCP 47 locale code. (An API such as that would not be appropriate for GJS because a `navigator` object doesn't make sense for our environment. Also, we probably want an API that converts any POSIX locale, not just the current one.)
- From a quick search, Node.js, Deno, and Bun do not have such a facility.
- [ICU's code to convert POSIX locale into ICU locale](https://github.com/unicode-org/icu/blob/main/icu4c/source/common/putil.cpp#L1691), which can then be converted to BCP 47.https://gitlab.gnome.org/GNOME/gjs/-/issues/590Segmentation fault with `Gio.File.move_async()` progress callback2024-03-22T00:20:08ZAndy HolmesSegmentation fault with `Gio.File.move_async()` progress callback# System information #
What is your operating system and version? Fedora Silverblue 39
What is your version of GJS? gjs 1.79.1 (df2bbbbc)
If the bug is related to GNOME Shell, what is your version of GNOME Shell? N/A
# Bug information...# System information #
What is your operating system and version? Fedora Silverblue 39
What is your version of GJS? gjs 1.79.1 (df2bbbbc)
If the bug is related to GNOME Shell, what is your version of GNOME Shell? N/A
# Bug information #
## Steps to reproduce ##
Segfault is triggered when a `GFileProgressCallback` is defined for `Gio.File.move_async()`. This callback type can be passed to `Gio.File.copy_async()` without problem, though.
```js
import GLib from 'gi://GLib';
import Gio from 'gi://Gio';
Gio._promisify(Gio.File.prototype, 'move_async');
const [source] = Gio.File.new_tmp(null);
const target = Gio.File.new_for_path('test-move.txt');
await source.move_async(
target,
Gio.FileCopyFlags.NONE,
GLib.PRIORITY_DEFAULT,
null, // Gio.Cancellable
() => {}); // Gio.FileProgressCallback
```
## Current behaviour ##
```
Thread 1 "gjs" received signal SIGSEGV, Segmentation fault.
classify_argument (type=type@entry=0x7fff005ed6e0, classes=classes@entry=0x7fffffffd810, byte_offset=byte_offset@entry=0) at ../src/x86/ffi64.c:164
164 switch (type->type)
(gdb) bt
#0 classify_argument (type=type@entry=0x7fff005ed6e0, classes=classes@entry=0x7fffffffd810, byte_offset=byte_offset@entry=0) at ../src/x86/ffi64.c:164
#1 0x00007ffff7e3477d in examine_argument (type=type@entry=0x7fff005ed6e0, classes=classes@entry=0x7fffffffd810, in_return=in_return@entry=false, pngpr=pngpr@entry=0x7fffffffd80c, pnsse=pnsse@entry=0x7fffffffd808)
at ../src/x86/ffi64.c:359
#2 0x00007ffff7e39a0e in ffi_closure_unix64_inner (cif=<optimized out>, fun=<optimized out>, user_data=<optimized out>, rvalue=<optimized out>, reg_args=<optimized out>, argp=0x7fffffffd950 "\200\331\377\377\377\177")
at ../src/x86/ffi64.c:847
#3 0x00007ffff7e3a278 in ffi_closure_unix64 () at ../src/x86/unix64.S:303
#4 0x00007ffff7a2f50a in move_async_progress_in_main () at ../gio/gfile.c:6424
#5 0x00007ffff7ec072d in g_idle_dispatch (source=0x7fffd4002300, callback=0x7ffff7a2f4f0 <move_async_progress_in_main>, user_data=0x7fffd4001c60) at ../glib/gmain.c:6282
#6 0x00007ffff7ec3dfc in g_main_dispatch (context=0x4458c0) at ../glib/gmain.c:3476
#7 g_main_context_dispatch_unlocked (context=0x4458c0) at ../glib/gmain.c:4284
#8 0x00007ffff7f1ed58 in g_main_context_iterate_unlocked.isra.0 (context=context@entry=0x4458c0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:4349
#9 0x00007ffff7ec1a73 in g_main_context_iteration (context=0x4458c0, may_block=1) at ../glib/gmain.c:4414
#10 0x00007ffff7ce854b in Gjs::MainLoop::spin(GjsContextPrivate*) (this=0x459d30, gjs=0x459c90) at ../gjs/mainloop.cpp:37
#11 0x00007ffff7cc914f in GjsContextPrivate::eval_module(char const*, unsigned char*, _GError**)
(this=0x459c90, identifier=0x599a10 "file:///var/home/andrew/Projects/gjs-guide/src/guides/gio/file-operations/gfileMove.js", exit_status_p=0x7fffffffdd7f "", error=0x7fffffffdd98) at ../gjs/context.cpp:1561
#12 0x00007ffff7cc849b in gjs_context_eval_module(GjsContext*, char const*, uint8_t*, GError**)
(js_context=0x459e10, identifier=0x599a10 "file:///var/home/andrew/Projects/gjs-guide/src/guides/gio/file-operations/gfileMove.js", exit_code=0x7fffffffdd7f "", error=0x7fffffffdd98) at ../gjs/context.cpp:1329
#13 0x0000000000402d7a in define_argv_and_eval_script(_GjsContext*, int, char* const*, char const*, unsigned long, char const*)
(js_context=0x459e10, argc=0, argv=0x7fffffffe010, script=0x4554a0 "import GLib from 'gi://GLib';\nimport Gio from 'gi://Gio';\n\nGio._promisify(Gio.File.prototype, 'move_async');\n\nconst [source] = Gio.File.new_tmp(null);\nconst target = Gio.File.new_for_path('test-move.t"..., len=376, filename=0x42bf10 "gfileMove.js") at ../gjs/console.cpp:205
#14 0x0000000000403979 in main(int, char**) (argc=3, argv=0x7fffffffdff8) at ../gjs/console.cpp:393
```
## Expected behaviour ##
Callback should be invoked without crash.GNOME 47Philip ChimentoPhilip Chimentohttps://gitlab.gnome.org/GNOME/gjs/-/issues/588Implement import.meta.resolve2024-03-12T05:55:15ZSonny Pierssonnyp@gnome.orgImplement import.meta.resolveGetting a file relative to the current script is difficult, specially when you have to take care of both `file` and `resource` protocols.
The `import.meta.resolve` standard is a nice way to solve it as it returns a uri string and is ava...Getting a file relative to the current script is difficult, specially when you have to take care of both `file` and `resource` protocols.
The `import.meta.resolve` standard is a nice way to solve it as it returns a uri string and is available on all major JS runtimes. Gio has a `File_new_for_uri` API that is perfect for this.
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve
* https://docs.deno.com/runtime/manual/runtime/import_meta_api
* https://bun.sh/docs/api/import-meta
* https://nodejs.org/api/esm.html#importmetaresolvespecifier
* https://github.com/wintercg/import-meta-registry
One of the use case is Workbench, we need a way for users to load files relative to the script. We currently offer the non-standard `workbench.resolve` API which does the same but we would like a standard solution.
An other one is using `import.meta.resolve` together with a helper function to build GTK interfaces https://gitlab.gnome.org/GNOME/gjs/-/merge_requests/853https://gitlab.gnome.org/GNOME/gjs/-/issues/587TextDecoder should accept GBytes2024-03-12T05:54:54ZSonny Pierssonnyp@gnome.orgTextDecoder should accept GBytes`TextDecoder.decode` should accept `GBtytes`
* https://gjs-docs.gnome.org/gjs/encoding.md#textdecoder
* https://gjs-docs.gnome.org/glib20\~2.0/glib.bytes
> i don't see a problem treating GBytes as equivalent to a Uint8Array in that way...`TextDecoder.decode` should accept `GBtytes`
* https://gjs-docs.gnome.org/gjs/encoding.md#textdecoder
* https://gjs-docs.gnome.org/glib20\~2.0/glib.bytes
> i don't see a problem treating GBytes as equivalent to a Uint8Array in that way, i believe they largely behave the same way
https://matrix.to/#/!pOGgkAueAsusiyFCTb:matrix.org/$1699258439197uxeha:gnome.org?via=gnome.org&via=matrix.org&via=libera.chat
---
Getting a string value in GJS can sometimes feel unnecessary difficult.
For example
```plaintext
const bytes = output_stream.steal_as_bytes();
const text_decoder = new TextDecoder("utf-8");
return text_decoder.decode(bytes.toArray().buffer);
```
We can make this slightly better by accepting GBytes in TextDecoder
```plaintext
const bytes = output_stream.steal_as_bytes();
const text_decoder = new TextDecoder("utf-8");
return text_decoder.decode(bytes); // this changed
```Sriyansh ShivamSriyansh Shivamhttps://gitlab.gnome.org/GNOME/gjs/-/issues/583Document Error.matches2024-03-12T05:54:34ZSonny Pierssonnyp@gnome.orgDocument Error.matchesWe should document `Error.matches` and how to deal with errors. Happy to but not sure what's the best place?
Maybe a new doc "Error handling" ?
See https://github.com/sonnyp/Workbench/pull/704#pullrequestreview-1700790533
cc @andyho...We should document `Error.matches` and how to deal with errors. Happy to but not sure what's the best place?
Maybe a new doc "Error handling" ?
See https://github.com/sonnyp/Workbench/pull/704#pullrequestreview-1700790533
cc @andyholmesSonny Pierssonnyp@gnome.orgSonny Pierssonnyp@gnome.orghttps://gitlab.gnome.org/GNOME/gjs/-/issues/582Dynamic import hangs if thread default main context != global default main co...2024-03-12T05:54:24ZAleksandr MezinDynamic import hangs if thread default main context != global default main context# System information #
What is your operating system and version? _Fedora 39_
What is your version of GJS? _1.78.0-2.fc39_
# Bug information #
## Steps to reproduce ##
`# cat main.js`
```js
const { GLib } = imports.gi;
function impo...# System information #
What is your operating system and version? _Fedora 39_
What is your version of GJS? _1.78.0-2.fc39_
# Bug information #
## Steps to reproduce ##
`# cat main.js`
```js
const { GLib } = imports.gi;
function import_sync(mod) {
let result;
let exception;
const ctx = GLib.MainContext.new();
const loop = GLib.MainLoop.new(ctx, true);
ctx?.push_thread_default();
try {
import(mod).then(res => {
result = res;
}).catch(ex => {
exception = ex;
logError(ex);
}).finally(() => {
loop.quit();
});
printerr('run');
loop.run();
printerr('done');
} finally {
ctx?.pop_thread_default();
}
if (exception)
throw exception;
return result;
}
import_sync('./aux.js').run();
```
`# cat aux.js`
```js
export function run() {
printerr('Success!!!');
}
```
## Current behaviour ##
```
# gjs main.js
run
```
and hangs.
## Expected behaviour ##
After `const ctx = GLib.MainContext.new();` replaced with `const ctx = null;` in `main.js`:
```
# gjs main.js
run
done
Success!!!
```https://gitlab.gnome.org/GNOME/gjs/-/issues/574Constructing a typedef/alias fails2024-03-16T06:10:21ZBilal Elmoussaouibil.elmoussaoui@gmail.comConstructing a typedef/alias failsFor example Gtk exposes GtkAllocation as an alias to GdkRectangle; but trying to construct a GtkAllocation with
```js
new Gtk.Allocation();
```
would fail with `TypeError: Gtk.Allocation is not a constructor`
compared to
```js
new Gdk....For example Gtk exposes GtkAllocation as an alias to GdkRectangle; but trying to construct a GtkAllocation with
```js
new Gtk.Allocation();
```
would fail with `TypeError: Gtk.Allocation is not a constructor`
compared to
```js
new Gdk.Rectangle();
```
which works as expected.
I would expect that the constructor is mapped for the aliased type as well as any function the aliased type has.https://gitlab.gnome.org/GNOME/gjs/-/issues/573Registering an GEnum with GJS2024-03-12T05:44:38ZSonny Pierssonnyp@gnome.orgRegistering an GEnum with GJSIt's currently not possible but would be particularly useful, specially with https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.EnumListModel.html
We could override `enum_register_static`
Work started here apparently https:...It's currently not possible but would be particularly useful, specially with https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.EnumListModel.html
We could override `enum_register_static`
Work started here apparently https://gitlab.gnome.org/GNOME/gjs/-/commit/e96d80e182a14a31e728764da880df5194b23b9bhttps://gitlab.gnome.org/GNOME/gjs/-/issues/568Flaky test follow-up from "Draft: Port to mozjs115"2024-03-12T05:44:25ZPhilip ChimentoFlaky test follow-up from "Draft: Port to mozjs115"The following discussion from !855 should be addressed:
- [ ] @xry111 started a [discussion](https://gitlab.gnome.org/GNOME/gjs/-/merge_requests/855#note_1785250): (+3 comments)
> If I delete all other test cases in `testGObjectDe...The following discussion from !855 should be addressed:
- [ ] @xry111 started a [discussion](https://gitlab.gnome.org/GNOME/gjs/-/merge_requests/855#note_1785250): (+3 comments)
> If I delete all other test cases in `testGObjectDestructionAccess.js` (only keeping one `it` entry `can be toggled up-down from various threads while getting a GWeakRef from main`), the test even fails with JS 102. So I guess the test is just some sort of flaky, or am I missing something here?
>
> ```
> 1..1
> not ok 1 Access to destroyed GObject can be toggled up-down from various threads while getting a GWeakRef from main
> # Message: Expected [object instance wrapper GType:GLocalFile jsobj@0x240de57ff60 native@0x55e552631c70] to be null.
> # Stack:
> # error properties: Object({ matches: Function })
> # <Jasmine>
> # @/home/xry111/git-repos/gjs/installed-tests/js/testGObjectDestructionAccess.js:62:41
> # <Jasmine>
> # setTimeout/source<@resource:///org/gnome/gjs/modules/esm/_timers.js:72:9
> # _init/GLib.MainLoop.prototype.runAsync/</<@resource:///org/gnome/gjs/modules/core/overrides/GLib.js:266:34
> ```
>
> @3v1n0 can you take a look?
@3v1n0:
> Not too shortly sorry, cause I've not setup mozjs 115 locally, however it would be interesting to see what you get on `GjsTestTools.get_saved_ref_count()` before clearing, and maybe calling gc twice or wait a bit more...
@xry111:
> If you only have mozjs 102, you can try removing all other test cases, making `testGObjectDestructionAccess.js` only contain one `it` entry for "can be toggled up-down from various threads while getting a GWeakRef from main". Then I guess you can reproduce the failure with 102. I found this when I tried to reduce the test sample for debugging...
@xry111:
> `GjsTestTools.get_saved_ref_count()` was 2 before `GjsTestTools.clear_saved();`. And calling `System.gc()` 5 times does not fix the issue.
@xry111:
> `GJS_DEBUG_TOPICS="JS KP ALV"` shows some difference. In the failed test:
```
System.gc() start
JS KP ALV: GjsMaybeOwned 0x561e2e9ed700 update_after_gc()
System.gc() done
```
> In the succeeded test:
```
System.gc() start
JS KP ALV: GjsMaybeOwned 0x55d537e416b8 trace()
JS KP ALV: GjsMaybeOwned 0x55d537da2a90 update_after_gc()
JS KP ALV: GjsMaybeOwned 0x55d537da2a90 reset()
JS KP ALV: GjsMaybeOwned 0x55d537da2a90 destroyed
System.gc() done
```
For now, I've disabled the flaky test. It should be reinstated when this is fixed.https://gitlab.gnome.org/GNOME/gjs/-/issues/567Revamp DBus tooling2024-03-12T05:44:11ZJonas DreßlerRevamp DBus toolingThe current tooling for implementing DBus interfaces in gjs is far from perfect, sometimes simple types work, sometimes GValues have to be used, and it's often unclear when.
Another thing is that tuples in dbus type descriptions are des...The current tooling for implementing DBus interfaces in gjs is far from perfect, sometimes simple types work, sometimes GValues have to be used, and it's often unclear when.
Another thing is that tuples in dbus type descriptions are described using arrays on the javascript side, but JS arrays are also used for actual array types in dbus, leading to weird things like this (note the three arrays with `[[[`):
```javascript
<method name="GetTechnologies">
<arg name="technologies" type="a(oa{sv})" direction="out"/>
</method>
GetTechnologies() {
return new GLib.Variant('(a(oa{sv}))', [[
[
'/net/connman/technology/wifi',
{
'Name': GLib.Variant.new_string('WiFi'),
},
'/net/connman/technology/bluetooth',
{
'Name': GLib.Variant.new_string('Bluetooth'),
},
]
]]);
}
```
Not sure what the best path to improve the situation here is without breaking existing code, maybe it would already be enough to encourage only using GVariants for everything dbus, then we could rely on the existing documentation and examples of GDBus.https://gitlab.gnome.org/GNOME/gjs/-/issues/566Better GNOME app JavaScript template2024-03-12T05:43:34ZSonny Pierssonnyp@gnome.orgBetter GNOME app JavaScript templateWe need a better template to make it easier for JavaScript developers to get started making apps. Including encoouraging Shell extensions from making apps instead of extensions.
We talked about it a bit with @andyholmes
here are some...We need a better template to make it easier for JavaScript developers to get started making apps. Including encoouraging Shell extensions from making apps instead of extensions.
We talked about it a bit with @andyholmes
here are some ideas
* Blueprint enabled
* gjspack for bundling and `import Cat from './Cat.png'` (and avoid having to maintain gresource files by hand)
* more interesting default behavior with some links to various resources for learning including Workbench
* Types enabled?
* Ctrl+Shift+R to restart? We might need a GNOME Builder protocol
The template should use the GNOME Builder template format
The template should be accessible from
* GNOME Builder "Create project"
* GitHub
* Gitlab?
We should promote it and deprecate/archive the old ones like https://github.com/gcampax/gtk-js-apphttps://gitlab.gnome.org/GNOME/gjs/-/issues/565Decide whether to remove linux RSS GC trigger2023-08-07T19:08:08ZPhilip ChimentoDecide whether to remove linux RSS GC triggerThe following discussion from !870 should be addressed:
- [ ] @ptomato started a [discussion](https://gitlab.gnome.org/GNOME/gjs/-/merge_requests/870#note_1801624): (+1 comment)
> Should we remove the linux RSS trigger as well? (I...The following discussion from !870 should be addressed:
- [ ] @ptomato started a [discussion](https://gitlab.gnome.org/GNOME/gjs/-/merge_requests/870#note_1801624): (+1 comment)
> Should we remove the linux RSS trigger as well? (I'm also happy to merge this and remove it later.)
>
> @hadess Philip W said you might be able to help answer whether using the low memory monitor is sufficient for what the linux RSS trigger currently does. (The current machinery is in https://gitlab.gnome.org/GNOME/gjs/-/blob/master/gjs/jsapi-util.cpp#L469-544)https://gitlab.gnome.org/GNOME/gjs/-/issues/557Connecting to signal of a GstElement errors with "too much recursion"2024-03-30T01:42:16ZRaihanConnecting to signal of a GstElement errors with "too much recursion"# System information #
OS = ArchLinux
gjs version = 1.76.2
# Bug information #
## Steps to reproduce ##
Run this code
```
const { Gst, GLib } = imports.gi;
Gst.init(null);
const pipelineStr = 'pulsesrc ! audioconvert ! audio/x-raw,form...# System information #
OS = ArchLinux
gjs version = 1.76.2
# Bug information #
## Steps to reproduce ##
Run this code
```
const { Gst, GLib } = imports.gi;
Gst.init(null);
const pipelineStr = 'pulsesrc ! audioconvert ! audio/x-raw,format=S16LE,rate=44100,channels=2 ! appsink name=analysis_sink caps=audio/x-raw,format=S16LE,rate=44100,channels=2 emit-signals=true';
const pipeline = Gst.parse_launch(pipelineStr);
const analysisSink = pipeline.get_child_by_name('analysis_sink');
function analyzeAudio(appsink, data) {
console.log('trying to pull buffer');
return Gst.FlowReturn.OK;
}
analysisSink.connect('new-sample', analyzeAudio);
pipeline.set_state(Gst.State.PLAYING);
const mainLoop = GLib.MainLoop.new(null, false);
mainLoop.run();
pipeline.set_state(Gst.State.NULL);
```
## Current behaviour ##
```
(gjs:4083): Gjs-CRITICAL **: 16:13:57.039: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.049: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.059: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.069: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.079: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.089: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.099: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.109: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.119: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.129: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.139: JS ERROR: too much recursion
@test.js:13:10
(gjs:4083): Gjs-CRITICAL **: 16:13:57.149: JS ERROR: too much recursion
@test.js:13:10
```
## Expected behaviour ##
The callback function should be called.https://gitlab.gnome.org/GNOME/gjs/-/issues/550Import map2024-03-12T05:34:51ZLorenzo MigliettaImport map# Description #
Import maps are a [WICG proposal](https://github.com/WICG/import-maps), already used by the Deno runtime.
In GJS it's hard to import arbitrary npm modules, therefore we often need to use bundlers and other external progra...# Description #
Import maps are a [WICG proposal](https://github.com/WICG/import-maps), already used by the Deno runtime.
In GJS it's hard to import arbitrary npm modules, therefore we often need to use bundlers and other external programs.
Import maps could bypass the problem of using bundlers.
Example: I can download the required js dependencies manually, using tools as [download-esm](https://github.com/simonw/download-esm).
Let's say I want to use `solid-js`.
```bash
download-esm solid-js ./downloaded-modules
```
Then in the import map I'm going to write
```
{
imports: {
"solid-js": "./downloaded-modules/solid-js-v1234928734987239478-asdf.js"
}
}
```
and then in my `index.js` file I can use `solid-js` as a normal module
```
import solid from "solid-js"
// instead of `import x from ./downloaded-modules/solid-js-v1234928734987239478-asdf.js`
// which would make the file unportable
```
Now I can run index.js directly, with `gjs`, without any bundler or any external program.
```
gjs --import-map import_map.json -m index.js
```
Ideally an external program could manage the import-map, download the required dependencies and generate a lock file.
All of this, while not requiring any collaboration from gjs, except reading the import map.
# Prior Art #
https://deno.com/manual@v1.33.4/basics/import_maps#import-mapsEvan Welshcontact@evanwelsh.comEvan Welshcontact@evanwelsh.comhttps://gitlab.gnome.org/GNOME/gjs/-/issues/548GStreamer's `CLOCK_TIME_NONE` is too large for JavaScript.2024-03-12T05:26:33ZShema Angelo VerlainGStreamer's `CLOCK_TIME_NONE` is too large for JavaScript.I'm making a Gstreamer app, and whenever I need to do stuff like:
```js
const state = this.playbin.get_state(Gst.CLOCK_TIME_NONE)[1];
if (state === Gst.State.PLAYING) {
this.pause();
} else {
this.play();
}
//.....I'm making a Gstreamer app, and whenever I need to do stuff like:
```js
const state = this.playbin.get_state(Gst.CLOCK_TIME_NONE)[1];
if (state === Gst.State.PLAYING) {
this.pause();
} else {
this.play();
}
//...
```
it fails, because `Gst.CLOCK_TIME_NONE` is higher than the max number in JavaScript. I get the following error:
```
(com.vixalien.muzika:470893): Gjs-WARNING **: 13:15:26.081: Value 18446744073709551615 cannot be safely stored in a JS Number and may be rounded
(com.vixalien.muzika:470893): Gjs-CRITICAL **: 13:15:26.081: JS ERROR: Error: Argument timeout: value is out of range for uint64
play_pause@resource:///com/vixalien/muzika/js/main.js:14487:32
```
When I use `Number.MAX_SAFE_INTEGER` instead of `Gst.CLOCK_TIME_NONE`, it works.
I think it might be a good solution to override `Gst.CLOCK_TIME_NONE` to `Number.MAX_SAFE_INTEGER` if that's possible.
Note that using `Number.MAX_VALUE` doesn't work either, and this throws: `JS ERROR: Error: Argument timeout: value is out of range for uint64`