I’m trying to port a Gnome-shell app to version 45
I have the following code:
const ExtensionUtils = imports.misc.extensionUtils; // Updated import for better practice
const Me = ExtensionUtils.getCurrentExtension();
Following the guide:
https://gjs.guide/extensions/upgrading/gnome-shell-45.html
This should be:
import * as MyModule from './MyModule.js';
However I get the following error message:
ReferenceError: Me is not defined
Keep in mind I have no experience with gnome-shell
andyholmes
(Andy Holmes)
October 2, 2024, 6:28pm
2
This is simply because you haven’t declared the variable Me
or assigned anything to it.
You are probably looking for Extension.lookupByURL()
, which is documented in the Extension (ESModule) topic page :
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
let extensionObject = Extension.lookupByUUID('example@gjs.guide');
Thanks for the help @andyholmes !
This result in:
TypeError: Me is null
I’m sure I took the right UUID from the metadata.json.
This is the following code where the error occure:
this.extensionString = `[${Me.metadata.name}] `; // String interpolation for clarity
Any help appriciated
fmuellner
(Florian Müllner)
October 3, 2024, 5:43pm
4
const Me = Extension.lookupByUUID('my-uuid@example.com');
cannot be used at the toplevel.
That is because the code is evaluated while gnome-shell imports the module, and therefore before it can construct the extension object that the function returns.
If this is inside your main extension class, then
this.extensionString = `[${this.metadata.name}]`;
should work.
Thanks for your help @fmuellner !
Keep in mind that it is a long time I worked with javascript.
The first file I am porting to Gnome-shell 45 is the console file for error reporting.
So it’s not the main extension file.
I now get the error message:
Error: Console did not pass metadata to parent
Google didn’t help much.
I’m looking at the following:
https://gjs.guide/extensions/overview/anatomy.html
Here the whole file:
"use strict";
//const ExtensionUtils = imports.misc.extensionUtils; // Updated import for better practice
//const Me = ExtensionUtils.getCurrentExtension();
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
//import {ExtensionPreferences} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
//extensionObject = Extension.lookupByUUID('gnomeemailtray46@patrick.libert.com');
//class Console {
export default class Console extends Extension {
/**
* @param {ExtensionMeta} metadata
**/
constructor(metadata) {
super(metadata);
this.extensionString = `[${this.metadata.name}]`; // String interpolation for clarity
//const gettextDomain = this.metadata['gettext-domain'];
}
log(...args) {
log(this.extensionString + args.join(' ')); // Ensures arguments are space-separated
}
error(err) {
this.log(err.message, err.stack); // Logs both the error message and stack trace
}
json(obj) {
this.log(JSON.stringify(obj, null, 2)); // Pretty-print JSON for readability
}
}
// Using `const` instead of `var` to declare `console`, which is now best practice
const console = new Console();
andyholmes
(Andy Holmes)
October 4, 2024, 4:46pm
6
console
/Console
is a reserved global name/class already, so it probably thinks you are trying to construct one.
It’s common practice to call the Extension
subclass something like ConsoleExtension
, since that will show up in the logs as well.
@andyholmes
This seems not to be the problem.
Changed everything.
Still:
Error: ConsoleExtension did not pass metadata to parent
andyholmes
(Andy Holmes)
October 4, 2024, 6:38pm
8
That’s probably a result of this line, then. This line is not necessary in your extension, but when you call new Console(<metadata should be here>)
.
When GNOME Shell constructs your extension, it will pass the metadata
object.
fmuellner
(Florian Müllner)
October 4, 2024, 7:15pm
9
The issue is that an Extension
subclass is used for something that isn’t the extension entry point, and ends up not being constructed by gnome-shell.
There simply is no neat trick that someone could apply to get access to any information from the extension object before that object is constructed.
If you want to define your own console
object that uses metadata from the extension, then you have several options:
only construct the console object when your extension is enabled
create it with placeholder values, and update it with the real metadata when it becomes available
use a getter for this.extensionString
so that you can cache its value lazily (that is, when first used)
I’m sure there are other options to pick from.
I removed the line:
const console = new Console();
and it seems to work.
I’m now already 3 gnome-shell javascript files further.
Next question that I don’t find in google.
I ported:
const Soup = imports.gi.Soup;
to
import Soup from 'gi://Soup?version=3.0';
Don’t know how to port SessionAsync();
const Session = new Soup.SessionAsync();