How to make the following GNOME extension quick setting `enable` run and wait the completion of a given shell command?

```javascript
export default class QuickSettingsExampleExtension extends Extension {
enable() {
this._indicator = new ExampleIndicator();
Main.panel.statusArea.quickSettings.addExternalIndicator(this._indicator);
}

...
}
```
Feb 10, 11:26pm

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:

Using Gio.Subprocess

javascript
import 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);
                }
            });
        });
    }

    ...
}

Explanation:

  • 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.
  • Promise: The _runCommand method returns a Promise, so you can use await in your enable() method to wait for the command to finish before continuing.

Example Usage:

If you want to run echo "Hello, world!", replace 'your-shell-command-here' with your actual command.

Notes:

  • Error Handling: The example includes basic error handling. You can extend it to handle specific errors or log more details.
  • Dependencies: Ensure your extension imports Gio at the top.
  • GNOME Shell Version: This approach works for GNOME Shell 3.38 and later. For older versions, you might need to use GLib.spawn_command_line_async with a callback.

Using GLib.spawn_command_line_async (Legacy)

If you are targeting an older GNOME Shell version, you can use:

javascript
import 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?

Feb 10, 11:26pm

This is a shared conversation and may include unverified content that doesn't reflect Mistral AI's views. Login to resume chatting.