0

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 helloworld@klino.me: Error: Requiring Adw, version none: Requiring namespace 'Gtk' version '4.0', but '3.0' is already loaded
Tom Klino
  • 2,358
  • 5
  • 35
  • 60

1 Answers1

0

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 adding imports.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.)

ptomato
  • 56,175
  • 13
  • 112
  • 165
  • It's actually not that important to me to use the Adw lib, it just happened to be in the example to create a new window. The trick with adding `imports.gi.version['Gtk'] = '4.0'` unfortunately didn't help. Do you have any idea how I can create a window without the Adw lib? – Tom Klino Feb 27 '23 at 18:33