tl;dr
How do I create an empty window in a GNOME extension?
Context
I'm working on an extension that will manage several windows within one. One of the first things I'm trying to achieve is to create a new empty window.
What I've Tried
I've found an example that does exactly that (but not in an extension) like so:
import Gtk from "gi://Gtk?version=4.0";
import Adw from "gi://Adw?version=1";
import system from "system";
const application = new Adw.Application({
application_id: "com.example.Application",
});
application.connect("activate", () => {
// create a Gtk Window belonging to the application itself
const window = new Gtk.ApplicationWindow({
application,
title: "Welcome to GNOME",
});
window.present();
});
/*
* Run the application, exit with the value returned by
* running the program
*/
const exit_code = application.run([system.programInvocationName, ...ARGV]);
system.exit(exit_code);
So I tried the following in my extension:
const Gtk = imports.gi.Gtk;
const Adw = imports.gi.Adw;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const globals = {
_version: "v4"
}
function enable() {
log(`enabling ${Me.metadata.name} ${globals._version}`);
const application = new Adw.Application({
application_id: "com.example.Application"
})
let testWindow = Gtk.ApplicationWindow.new(application)
testWindow.present_with_time(Date.now())
}
But when testing (in a nested shell), I'm getting the following error:
(gnome-shell:234231): Gjs-WARNING **: 12:51:46.718: JS ERROR: Extension [email protected]: Error: Requiring Adw, version none: Requiring namespace 'Gtk' version '4.0', but '3.0' is already loaded
GNOME Shell extensions are in-process of GNOME Shell. That means, you can't load libraries that conflict with libraries used by GNOME Shell. For example, you can't load GTK 3 and GTK 4 in the same process, because their ABIs conflict with each other.
The Adwaita library requires GTK 4 and the GNOME Shell process has already loaded GTK 3. That's why you are seeing this error message.
It may be that GTK 3 is only loaded because you didn't specify a version of
imports.gi.Gtk. If that's the case, try addingimports.gi.versions['Gtk'] = '4.0';before the import.On the other hand, it may be that you are testing your extension on an older version of GNOME Shell that loads GTK 3 for other purposes. There are a few things you could do: adapt your code for GTK 3; make Adwaita an optional dependency of your extension so that it's only loaded if possible, and maintain 2 code paths; or declare that your extension requires a recent enough version of GNOME Shell that you can use GTK 4. (And of course, do your development and testing on that version.)