Skip to content

Introduce runAsync() to run mainloops without blocking module resolution

Evan Welsh requested to merge ewlsh/main-loop-hooks into master

With top-level await all modules are now promises, if Gtk.Application.run() or GLib.MainLoop.run() is called within a module it will block all other promises as run() is a synchronous, blocking function. To work around this there is now a setMainLoopHook function exposed which runs a callback after module resolution is complete. This allows APIs to "install" a mainloop asynchronously.

For Gio.Application, Gtk.Application, and GLib.MainLoop there are now runAsync() versions of their run() functions. runAsync() returns a Promise which will resolve once the mainloop has exited.

Gtk.Application.prototype.runAsync

import Gtk from "gi://Gtk";

const application = new Gtk.Application({
    application_id: "what.ev.er",
});

application.connect("activate", () => {
    const window = new Gtk.ApplicationWindow({ application })

    Promise.resolve().then(() => {
        log('RESOLVED');
    });

    const button = new Gtk.Button({ label: 'Test' });
    button.connect('clicked', () => {
        Promise.resolve().then(() => {
            log('test');
        });
    });
    window.set_child(button);
    window.present();
});

await application.runAsync([]);

log('Exiting...');

Fixes #468 (closed)

Edited by Evan Welsh

Merge request reports