Note: Binary files aren't shown on the web site. To see all files, please download the extension zipfile.
Version | Status |
---|---|
72 | Inactive |
71 | Inactive |
70 | Rejected |
69 | Rejected |
68 | Rejected |
67 | Rejected |
66 | Rejected |
65 | Rejected |
64 | Inactive |
63 | Inactive |
62 | Inactive |
61 | Inactive |
60 | Inactive |
59 | Inactive |
58 | Inactive |
57 | Inactive |
56 | Inactive |
55 | Inactive |
54 | Inactive |
53 | Inactive |
52 | Inactive |
51 | Inactive |
50 | Rejected |
49 | Rejected |
48 | Inactive |
47 | Inactive |
46 | Inactive |
45 | Inactive |
44 | Inactive |
43 | Rejected |
42 | Rejected |
41 | Inactive |
40 | Inactive |
39 | Rejected |
38 | Inactive |
37 | Inactive |
36 | Inactive |
35 | Inactive |
34 | Inactive |
33 | Inactive |
32 | Inactive |
31 | Inactive |
30 | Inactive |
29 | Inactive |
28 | Inactive |
27 | Inactive |
26 | Inactive |
25 | Inactive |
24 | Inactive |
23 | Inactive |
22 | Inactive |
21 | Inactive |
20 | Inactive |
19 | Inactive |
18 | Inactive |
17 | Inactive |
16 | Inactive |
15 | Inactive |
14 | Inactive |
13 | Inactive |
12 | Inactive |
11 | Rejected |
10 | Inactive |
9 | Inactive |
8 | Inactive |
7 | Inactive |
6 | Inactive |
5 | Inactive |
4 | Inactive |
3 | Inactive |
2 | Inactive |
1 | Inactive |
Please remove `.run_dispose()`: - line 45 extension.js - line 51-53 libs/preferences.js As mentioned in the doc: > This function should only be called from object system implementations. https://gjs-docs.gnome.org/gobject20~2.0/gobject.object#method-run_dispose
It's safe to use `run_dispose()` in "destructors" (the `destroy` function name implies that calling it will destroy the object). `run_dispose()` is heavy used in the GNOME Shell (see https://gitlab.gnome.org/search?search=run_dispose&nav_source=navbar&project_id=546&group_id=8&search_code=true&repository_ref=44.3), also this function is called inside `Clutter.actor.destroy()` (see https://gitlab.gnome.org/GNOME/mutter/-/blob/44.3/clutter/clutter/clutter-actor.c?ref_type=tags#L7672).
`run_dispose()` in `extension.js` is unnecessary. I don't think there is a valid reason for using it there but what happens when you don't use it on `libs/preferences.js`?
> `run_dispose()` in `extension.js` is unnecessary Can you explain why you think so? What's wrong with this? There's code in GNOME Shell that does exactly the same (see https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/44.3/js/ui/messageTray.js#L155 and derived classes).
When `PanelIndicator` instance is getting destroyed and null out, there won't be any reference remaining to `ClipboardManager`. As we discussed this with other reviewers in GNOME Matrix channel: > if anything outside of GJS tries to touch an object, it will probably segfault The question is, what are you trying to achieve with `run_dispose()` there that cannot be achieve without it?
> When `PanelIndicator` instance is getting destroyed and null out, there won't be any reference remaining to `ClipboardManager`. Yes, but the instance of ClipboardManager will live for a while (seconds or minutes, there is no way to know when exactly it will be destroyed). Now let's keep in mind any ancestor of GObject.Object, not just the ClipboardManager. As long as an object instance is not destroyed, it can still call handlers connected to its signals.To avoid this, we have to disconnect all handlers before the last reference to it is lost. Now let's imagine that I connected to 100 signals: I need to store 100 handler IDs, and then call `disconnect` 100 times. Calling `run_dispose()` disconnects all handlers from this object (https://discourse.gnome.org/t/locate-and-remove-memory-leaks-in-javascript/12957/2) as well as drops reference count to 0, automatically freeing all resources and memory of the object. This is the reason why `indicator.destroy()` is called before `indicator = null` inside `disable()`. The main problem may be "use after free" , but there is no such thing in my case.
I guess I should probably chime in, since you're referencing posts I've made :) `GObject.Object.run_dispose()` does *not* drop the reference count to `0`, nor does free all of a GObect's memory. The `dispose()` vfunc is used to break circular references between GObjects, and a correct object implementation must be able to handle `dispose()` being called more than once, and the object should be able to safely handle outside calls to its methods. Every implementation of a `::destroy` signal will state in its documentation, that anyone holding a reference must drop it (e.g. `g_object_unref()`) when the `::destroy` signal is emitted. Only when the reference count of an object drops `0` (i.e. every reference holds explicitly calls `g_object_unref()`) will the `GObject.Object.finalize()` vfunc be called. That is when the memory of a GObject is freed. Signal handlers only work in one direction, which is to say unless your `ClipboardManager` emits a signal, no connected handlers will be called. All you need for a safe, valid "destroy" function is: ``` destroy() { if (this._selection && this._selectionOwnerChangedId) { this._selection.disconnect(this._selectionOwnerChangedId); this._selectionOwnerChangedId = null; } } ``` This is 100% safe, and it is not possible for a handler to be called after this. When the last variable stops tracing the `ClipboardManager` instance, the signal handlers will be automatically disconnected via the normal dispose/finalize process.
Thanks!