To make your GNOME Shell extension's enable() method run and wait for the completion of a shell command, you need to use GNOME Shell's built-in utilities for running shell commands asynchronously. The most common way is to use Gio.Subprocess or GLib.spawn_command_line_async.
Here’s how you can modify your enable() method to run a shell command and wait for its completion before continuing:
Gio.Subprocessjavascriptimport Gio from 'gi://Gio'; export default class QuickSettingsExampleExtension extends Extension { async enable() { // Run your shell command and wait for completion await this._runCommand('your-shell-command-here'); // Continue with the rest of your enable logic this._indicator = new ExampleIndicator(); Main.panel.statusArea.quickSettings.addExternalIndicator(this._indicator); } async _runCommand(command) { return new Promise((resolve, reject) => { let proc = new Gio.Subprocess({ argv: ['/bin/sh', '-c', command], flags: Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE, }); proc.init(null); proc.communicate_utf8_async(null, null, (proc, res) => { try { let [, stdout, stderr] = proc.communicate_utf8_finish(res); if (proc.get_successful()) { log(`Command succeeded: ${stdout}`); resolve(); } else { log(`Command failed: ${stderr}`); reject(new Error(stderr)); } } catch (e) { logError(e, 'Failed to run command'); reject(e); } }); }); } ... }
Gio.Subprocess: This is the modern way to run shell commands in GNOME Shell extensions. It allows you to spawn a subprocess and handle its output and errors.communicate_utf8_async: This method runs the command asynchronously and allows you to wait for its completion using a Promise._runCommand method returns a Promise, so you can use await in your enable() method to wait for the command to finish before continuing.If you want to run echo "Hello, world!", replace 'your-shell-command-here' with your actual command.
Gio at the top.GLib.spawn_command_line_async with a callback.GLib.spawn_command_line_async (Legacy)If you are targeting an older GNOME Shell version, you can use:
javascriptimport GLib from 'gi://GLib'; _runCommand(command) { return new Promise((resolve, reject) => { GLib.spawn_command_line_async(command, (pid) => { GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, () => { resolve(); }); }); }); }
But this method does not capture output or errors, so Gio.Subprocess is recommended.
Question: What shell command do you want to run, and do you need to handle its output or errors in a specific way?